Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does the standard say about how calling clear on a vector changes the capacity?

This website implies that clearing a vector MAY change the capacity:

http://en.cppreference.com/w/cpp/container/vector/clear

Many implementations will not release allocated memory after a call to clear(), effectively leaving the capacity() of the vector unchanged.

But according to @JamesKanze this is wrong and the standard mandates that clear will not change capacity.

What does the standard say?

like image 750
Neil Kirk Avatar asked Aug 27 '13 14:08

Neil Kirk


People also ask

Does vector clear change capacity?

Using vector::clear function So, we're left with a vector of size 0 but some finite capacity. Starting with C++11, we can call the vector::shrink_to_fit function after clear() , which reduces the vector's capacity to fir the size. It works by “requesting” a reallocation on the vector.

What happens when you clear a vector?

clear() removes all the elements from a vector container, thus making its size 0. All the elements of the vector are removed using clear() function.

How does vector capacity increase?

Every time a vector's capacity is grown the elements need to be copied. If you 'amortize' this cost out over the lifetime of the vector, it turns out that if you increase the capacity by an exponential factor you end up with an amortized constant cost.

How do you reduce the capacity of a vector?

C++ std::vector Reducing the Capacity of a Vector In C++11 we can use the shrink_to_fit() member function for a similar effect: v. shrink_to_fit();


1 Answers

Depending on the version of the standard you are looking at, clear is defined as the equivalent of erase(begin(), end()), or (in C++11):
"Destroys all elements in a. Invalidates all references, pointers, and iterators referring to the elements of a and may invalidate the past-the-end iterator."

In neither case is it allowed to modify the capacity; the following code is guaranteed safe by the standard:

std::vector<int> v; for (int i = 0; i != 5; ++ i) {     v.push_back(i); } assert(v.capacity() >= 5); v.clear(); assert(v.capacity() >= 5); v.push_back(10); v.push_back(11); std::vector<int>::iterator i = v.begin() + 1; v.push_back(12); v.push_back(13); *i = 42;        //  i must still be valid, because none of                  //  the push_back would have required an                 //  increase of capacity 

(The reason for the change in wording in C++11: the committee didn't want to require MoveAssignable for clear, which would have been the case if it were defined in terms of erase.)

like image 112
James Kanze Avatar answered Sep 19 '22 05:09

James Kanze