Does Clearing a Vector Affect Its Capacity

Does clearing a vector affect its capacity?

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();

Does vector::erase reduce vector::capacity?

Not necessarily no. When reading the C++ standard (and cppreference proxies the standard remarkably well), if something is not explicitly mentioned, then assume such a something is not required.

It would possibly be sub-optimal for a C++ Standard Library implementation to do so.

std::vector resize(0) or clear() - but keep it's capacity

Actually the clear member function keeps the vector capacity unchanged. It only destroys (calls the destructor) each of the vector elements and sets the vector size to 0.

In this situation, at each iteration, I would call clear() to destroy all the vector elements, then call the member function reserve(size) which, in the case where the vector capacity is too small, will increase it to at least size.

Will a call to std::vector::clear() set std::vector::capacity() to zero?

It is specified that std::vector<T>::clear() affects the size. It might not affect the capacity. For resetting the capacity, use the swap trick:

    std::vector<int> v1;

// somehow increase capacity

std::vector<int>().swap(v1);

Note: Since this old answer is still getting upvotes (thus people read it), I feel the need to add that C++11 has added std::vector<...>::shrink_to_fit(), which requests the vector to remove unused capacity.

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

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.)

Does clear() in std::vector generates a memory leak?

Does clear() in std::vector generates a memory leak?

No.

But will this memory be free for the OS to allow other programs to use it or will it be available for my program to use it anywhere else?

OS can swap the memory to disk, to allow other programs to use the physical memory.

if the memory continues to be allocated only for this vector and I can't access it anymore

You can reuse the memory by adding new objects into the vector. Or release it by destroying the vector. The destructor absolutely guarantees to free the memory.

isn't it a memory leak like the ones we have with pointers?

No. A memory leak happens when the pointer to the memory is lost. But in this case the vector safely keeps track of the pointer, and frees it when it is destroyed.

Then clear() when used alone like this would be totally unsafe right?

clear isn't inherently unsafe, but the assumption that it will free the memory may be.

Is std::vector memory freed upon a clear?

The memory remains attached to the vector. That isn't just likely either. It's required. In particular, if you were to add elements to the vector again after calling clear(), the vector must not reallocate until you add more elements than the 1000 is it was previously sized to.

If you want to free the memory, the usual is to swap with an empty vector. C++11 also adds a shrink_to_fit member function that's intended to provide roughly the same capability more directly, but it's non-binding (in other words, it's likely to release extra memory, but still not truly required to do so).



Related Topics



Leave a reply



Submit