Does clearing a vector affect its capacity?

12,882

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.

Share:
12,882
Alan Turing
Author by

Alan Turing

Updated on June 03, 2022

Comments

  • Alan Turing
    Alan Turing almost 2 years

    I instantiate an std::vector foo(1000).

    foo.size() is now 1000 and foo.capacity() is also 1000.

    If I clear the vector with foo.clear(), the size() is now 0, but what is the capacity()? Does the standard say anything about that?

  • Björn Pollex
    Björn Pollex almost 13 years
    It might. The standard does not specify it, so you should not rely on it. Though most implementations do it that way.
  • Cat Plus Plus
    Cat Plus Plus almost 13 years
    In 0x, vector has shrink_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
    Johannes Schaub - litb almost 13 years
    Can 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
    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
    Johannes Schaub - litb almost 13 years
    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.
  • Armen Tsirunyan
    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
    Johannes Schaub - litb almost 13 years
    Ohh I see now. I was confused.
  • Armen Tsirunyan
    Armen Tsirunyan almost 13 years
    @sbi: Why? Please enlighten us :)
  • fredoverflow
    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
    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
    Armen Tsirunyan almost 13 years
    @Fred: If foo is empty, then this will make the capacity 0, no?
  • fredoverflow
    fredoverflow almost 13 years
    It will make the capacity as small as the implementation deems sensible.
  • doug65536
    doug65536 over 11 years
    I use std::swap(foo, ItemContainer()) and have typedef 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
    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
    curiousguy almost 11 years
    @BjörnPollex If the standard does not say that capacity can decrease, then it cannot.
  • Johannes Schaub - litb
    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
    curiousguy almost 11 years
    @JohannesSchaub-litb The spec says that after reserve(n) capacity is at least n. If nothing is said in the spec of resize about capacity it means that capacity is not allowed to change (unless there is a general statement that members of vector can shrink capacity). Unless the spec say that something can happen, it cannot happen.
  • Johannes Schaub - litb
    Johannes Schaub - litb almost 11 years
    @curious he did not call reserve
  • curiousguy
    curiousguy almost 11 years
    @JohannesSchaub-litb What allows vector to decrease capacity here?
  • Johannes Schaub - litb
    Johannes Schaub - litb almost 11 years
    @curiousguy i don't know. as i said, i am not familiar with it anymore.
  • Zan Lynx
    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
    curiousguy almost 8 years
    @ZanLynx No. The standard allows no such thing. If the standard doesn't allow it, then it shall not happen.