Does clearing a vector affect its capacity?
Solution 1
No, it doesn't. The capacity of a vector never decreases. That isn't mandated by the standard but it's so both in standard library implementations of VC++ and g++. In order to set the capacity just enough to fit the size, use the famous swap trick
vector<T>().swap(foo);
In C++11 standard, you can do it more explicitly:
foo.shrink_to_fit();
Solution 2
To clear a vector and consume as little capacity as possible, use the swap trick:
std::vector<T>().swap(foo);
This creates an empty vector, swaps its internals with foo
, and then destroys the temporary vector, getting rid of the elements that once belonged to foo
and leaving foo
as if it was freshly created.
Solution 3
The standard does not say anything about the effect of clear
on capacity
.
Alan Turing
Updated on June 03, 2022Comments
-
Alan Turing almost 2 years
I instantiate an
std::vector foo(1000)
.foo.size()
is now 1000 andfoo.capacity()
is also 1000.If I clear the vector with
foo.clear()
, thesize()
is now 0, but what is thecapacity()
? Does the standard say anything about that? -
Björn Pollex almost 13 yearsIt might. The standard does not specify it, so you should not rely on it. Though most implementations do it that way.
-
Cat Plus Plus almost 13 yearsIn 0x,
vector
hasshrink_to_fit
, but the standard remarks it's non-binding, which I presume means that implementation is not required to actually do that. -
Johannes Schaub - litb almost 13 yearsCan you please give a c++03 quote? It says that
erase(.begin(), .end())
invalidates all iterators and references after the point of erase. That doesn't seem to say anything about the capacity. -
Armen Tsirunyan almost 13 years@Johannes: I said that it's not mentioned in the standard! I said on most implementations it's so!
-
Johannes Schaub - litb almost 13 yearsU say that the capacity of a vector never decreases (even if no explicit call to "reserve" has happened). I cannot find the spec say so.
-
Armen Tsirunyan almost 13 years@Johannes: The spec doesn't say so. It just so happens to be implemented on VC++ and g++ implementations@
-
Johannes Schaub - litb almost 13 yearsOhh I see now. I was confused.
-
Armen Tsirunyan almost 13 years@sbi: Why? Please enlighten us :)
-
fredoverflow almost 13 years@Armen: Yes, you cannot pass rvalues to swap, but you can call swap on rvalues, hence my swapping of the arguments :)
-
sbi almost 13 years@Fred, Armen: The vector will be shrunk, but not empty. I see now that this is what you also wrote in the accompanying text, but it's not what actually was asked. (I still think it would be a valuable additional hint (you can shrink a vector by not clearing it!), but I think the original question should be answered first. (Oh, and I'd add a word about this being O(n).)
-
Armen Tsirunyan almost 13 years@Fred: If foo is empty, then this will make the capacity 0, no?
-
fredoverflow almost 13 yearsIt will make the capacity as small as the implementation deems sensible.
-
doug65536 over 11 yearsI use
std::swap(foo, ItemContainer())
and havetypedef std::vector<T> ItemContainer
somewhere else when possible. It is more recognizable (IMHO) to have a temporary passed as an argument than having it be the calling object and an lvalue. Your way is 100% fine though. -
curiousguy almost 11 years@JohannesSchaub-litb "U say that the capacity of a vector never decreases (even if no explicit call to "reserve" has happened). I cannot find the spec say so." It does not work like that; which part of the spec allows the capacity to decrease?
-
curiousguy almost 11 years@BjörnPollex If the standard does not say that capacity can decrease, then it cannot.
-
Johannes Schaub - litb almost 11 years@curiousguy i'm not familiar with that area of the spec anymore. but if nothing is said about the capacity value, its value is unspecified.
-
curiousguy almost 11 years@JohannesSchaub-litb The spec says that after
reserve(n)
capacity is at leastn
. If nothing is said in the spec ofresize
about capacity it means that capacity is not allowed to change (unless there is a general statement that members ofvector
can shrink capacity). Unless the spec say that something can happen, it cannot happen. -
Johannes Schaub - litb almost 11 years@curious he did not call reserve
-
curiousguy almost 11 years@JohannesSchaub-litb What allows
vector
to decrease capacity here? -
Johannes Schaub - litb almost 11 years@curiousguy i don't know. as i said, i am not familiar with it anymore.
-
Zan Lynx almost 8 years@curiousguy: Actually if the standards don't explicitly say what happens, then it is open to happen any way the implementation wants to do it.
-
curiousguy almost 8 years@ZanLynx No. The standard allows no such thing. If the standard doesn't allow it, then it shall not happen.