Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do I need to call clear() when I am done with a vector? [duplicate]

All of the questions that I have seen ask about managing memory when the elements of the vector are dynamically allocated/are pointers. My question is just about a vector that has been allocated on the stack, with a simple type, for example, int.

If I have the following code:

std::vector<int> vec(5);
for(int i = 0; i < vec.size(); i++) {
    std::cout << vec[i] << std::endl;
}

Do I need to call clear() when I am done?

like image 978
Falljah A. Ali Avatar asked Feb 28 '18 22:02

Falljah A. Ali


2 Answers

No.

Classes in C++ have a destructor that gets called when the class object goes out of scope or is deleted. While you are correct that std::vector dynamically allocates space under the hood, the std::vector destructor will deallocate the memory for you resulting in a happy leak-free program.

From the cppreference page, when the vector destructor is called it...

Destructs the container. The destructors of the elements are called and the used storage is deallocated. Note, that if the elements are pointers, the pointed-to objects are not destroyed.


Also note that from the cppreference on clear, the function...

Leaves the capacity() of the vector unchanged...

So when you call clear the memory isn't even actually being free'd! (see this SO question for more on what clear is actually doing)

like image 145
scohe001 Avatar answered Oct 03 '22 00:10

scohe001


If you are worried about freeing the memory allocated (and hence blocked for use elsewhere) in a (large) vector, you should

  1. make sure the scope/lifetime of the respective vector is limited to the region/time of its imminent use, so that its destruction automatically frees the memory.

  2. failing that (for whatever reason), you may

    vec.clear();          // reduces the size to 0, but not the capacity
    vec.shrink_to_fit();  // suggests to reduce the capacity to size
    assert(vec.capacity()==0);
    

Note that vector::clear() de-allocates no memory in vector (only memory, if any, dynamically allocated by the vector elements). vector::shrink_to_fit() suggests the reduction of the memory footprint of vector to its actual size, but the implementation can chose to ignore that request.

Finally, an alternative to clear() followed by shrink_to_fit() is the swap idiom (which also works prior to C++11):

vector<Tp>().swap(vec);
assert(vec.capacity()==0);

What happens here is that a new empty vector (of the same type) is constructed and then immediately swapped with vec, so that vec becomes empty (with zero size and capacity). Finally, because the new vector is a temporary (un-named) object, it is destructed, whereby de-allocating the memory originally kept with vec.

like image 34
Walter Avatar answered Oct 03 '22 00:10

Walter