std :: vector ridimensiona verso il basso

Lo standard C ++ sembra non rilasciare dichiarazioni riguardo gli effetti collaterali sulla capacità di resize(n) , con n < size() o clear() .

Fa una dichiarazione sul costo ammortizzato di push_back e pop_back – O (1)

Posso immaginare un’implementazione che faccia il solito tipo di modifiche di capacità agli algoritmi CLRS (es. Raddoppiare quando si ingrandisce, dimezzare quando si riduce la size to < capacity()/4 ). (Cormen Lieserson Rivest Stein)

Qualcuno ha un riferimento per eventuali restrizioni di implementazione?

Chiamare resize() con una dimensione più piccola non ha alcun effetto sulla capacità di un vector . Non libererà memoria.

L’idioma standard per liberare memoria da un vector è swap() con un vector temporaneo vuoto: std::vector().swap(vec); . Se si desidera ridimensionare verso il basso, è necessario copiare dal vettore originale in un nuovo vettore temporaneo locale e quindi scambiare il vettore risultante con il proprio originale.

Aggiornato: C ++ 11 ha aggiunto una funzione membro shrink_to_fit() per questo scopo, è una richiesta non vincolante per ridurre la capacity() a size() .

In realtà, lo standard specifica cosa dovrebbe accadere:

Questo è dal vector , ma il tema è lo stesso per tutti i contenitori ( list , deque , ecc …)

23.2.4.2 capacità vettoriale [lib.vector.capacity]

void resize(size_type sz, T c = T());

6) Effetti:

 if (sz > size()) insert(end(), sz-size(), c); else if (sz < size()) erase(begin()+sz, end()); else ; //do nothing 

Vale a dire: se la dimensione specificata per resize è inferiore al numero di elementi, tali elementi verranno cancellati dal contenitore. Per quanto riguarda la capacity() , ciò dipende da cosa erase() .

Non riesco a localizzarlo nello standard, ma sono abbastanza sicuro che clear() è definito come:

 void clear() { erase(begin(), end()); } 

Pertanto, gli effetti clear() ha su capacity() è anche legato agli effetti che erase() ha su di esso. Secondo lo standard:

23.2.4.3 modificatori vettoriali [lib.vector.modifiers]

 iterator erase(iterator position); iterator erase(iterator first, iterator last); 

4) Complessità: il distruttore di T è chiamato il numero di volte uguale al numero degli elementi cancellati ....

Ciò significa che gli elementi verranno distrutti, ma la memoria rimarrà intatta. erase() non ha alcun effetto sulla capacità, quindi anche resize() e clear() non hanno alcun effetto.

La capacità non diminuirà mai. Non sono sicuro che lo standard lo dichiari esplicitamente, ma è implicito: iteratori e riferimenti agli elementi vettoriali non devono essere invalidati da resize(n) se n < capacity() .

Come ho verificato per gcc (mingw) l’unico modo per liberare la capacità del vettore è quello che dice mattnewport. Lo si scambia con un altro vettore teporario. Questo codice lo rende per gcc.

 template void shrinkContainer(C &container) { if (container.size() != container.capacity()) { C tmp = container; swap(container, tmp); } //container.size() == container.capacity() }