Comment réduire la taille de std :: vector?

Existe-t-il un moyen de redimensionner un std::vector pour réduire sa capacité lorsque je n’ai plus besoin d’espace précédemment réservé?

Effective STL, par Scott Meyers, article 17: Utilisez l’astuce d’ swap pour réduire la capacité excédentaire.

 vector(persons).swap(persons); 

Après cela, les persons sont “réduites à s’adapter”.

Cela repose sur le fait que le constructeur de copie de vector n’alloue que la quantité de mémoire nécessaire pour les éléments à copier.

Si vous utilisez C ++ 11, vous pouvez utiliser vec.shrink_to_fit() . Dans VS2010 au moins, le swap est fait pour vous.

Créez un nouveau vecteur temporaire à partir du vecteur existant, puis appelez la méthode de permutation sur la méthode existante en transmettant le temporaire. Entrez le champ temporaire (maintenant avec l’ancien tampon surdimensionné).

Bonjour, votre vecteur a exactement la bonne taille pour son contenu.

Si cela ressemble à beaucoup de copie et d’allocation, gardez à l’esprit que c’est ce que fait le vecteur chaque fois qu’il doit redéfinir au-delà de sa limite réservée actuelle.

[Edit] Oui, je viens de dire la même chose que Sébastien en plus de mots. Un autre cas de condition de course stackoverflow 😉

L’astuce de swap est un moyen efficace de réduire la capacité d’un object, elle permute le contenu de mon vecteur avec une construction nouvellement créée par copie:

 vector(persons).swap(persons); 

Notez qu’il n’y a aucune garantie que persons.capacity (); après le tour de swap est égal à la taille: la capacité du vecteur (personnes) est la capacité que l’implémentation de la bibliothèque réserve aux vecteurs de taille personnes.size ().

C ++ 11 a introduit shrink_to_fit () .

shrink_to_fit () ainsi que l’astuce de swap ne garantissent pas que la taille de la capacité est effectivement réduite à la taille du vecteur.

Quoi qu’il en soit, shrink_to_fit () peut invalider vos iterators (si une réallocation se produit) ou ne peut pas: cela dépend de l’implémentation réelle de la bibliothèque.

Gardez à l’esprit que le truc d’échange nécessite personnes.size () pour copier les constructions de destructions Person et person.size (). Shrink_to_fit () pourrait éviter toute cette copie et laisser vos iterators valides. Pourrait. Mais de temps en temps, shrink_to_fit () est implémenté en terme de swap …

Vous recherchez un équivalent de QVector :: squeeze et je crains que cela n’existe pas explicitement dans la STL. Allez chercher la réponse de Sébastien si elle convient à votre implémentation STL.