Question

Is there a way to resize a std::vector to lower capacity when I no longer need previously reserved space?

Was it helpful?

Solution

Effective STL, by Scott Meyers, Item 17: Use the swap trick to trim excess capacity.

vector<Person>(persons).swap(persons);

After that, persons is "shrunk to fit".

This relies on the fact that vector's copy constructor allocates only as much as memory as needed for the elements being copied.

OTHER TIPS

If you're using C++11, you can use vec.shrink_to_fit(). In VS2010 at least, that does the swap trick for you.

Create a new, temporary, vector from the existing one then call the swap method on the existing one, passing the temporary one in. Let the temporary (now with the old, oversized, buffer) go out of scope.

Hey presto, your vector has exactly the right size for its contents.

If this sounds like a lot of copying and allocation - bear in mind that this is what vector does every time it has to realloc past its current reserved limit anyway.

[Edit] Yes, I just said the same as Sebastien in more words. Another case of stackoverflow race-condition ;-)

The swap trick is an effective way to reduce the capacity of an object, it swaps the content of my vector with a newly created one by copy construction:

vector<Person>(persons).swap(persons);

Notice that there is no guarantee that persons.capacity(); after the swap trick is equal to the size: the capacity of vector(persons) is the capacity the library implementation reserves to vectors of size persons.size().

C++11 introduced shrink_to_fit().

shrink_to_fit() as well as the swap trick does not guarantee the capacity size is effectively reduced to the size of the vector.

Anyway shrink_to_fit() can invalidate your iterators (if a reallocation happens) or cannot: it depends on the actual implementation of the library.

Bear in mind that the swap trick requires persons.size() copy constructions of Person and person.size() destructions. The shrink_to_fit() could avoid all this copying and could leave your iterators valid. Could. But from time to time it happens that shrink_to_fit() is implemented in terms of the swap trick...

You're looking for an equivalent of QVector::squeeze and I'm afraid it doesn't exist explicitely in the STL. Go for Sébastien's answer if it is correct for your STL implementation.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top