6

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?

  • 3
    Take a look at destructors. When the vector goes out of scope, it will be deallocated for you! This is one of the many reasons you've probably also seen people on this site preaching vectors over dynamically allocated arrays :) – scohe001 Feb 28 '18 at 22:02
  • 1
    `clear()` is unneeded. – Jarod42 Feb 28 '18 at 22:02
  • 1
    Elements of `std::vector` are always dynamically allocated, independently of whether the vector object itself is on the stack or on the heap (small buffer optimization cannot be used due to Standard constraints). Destruction of elements and deallocation of buffer is done automatically in destructor following RAII idiom, employed by all STL containers. – Daniel Langr Feb 28 '18 at 22:02
  • You don't need to do that. class Vector achieves RAII. – Raindrop7 Feb 28 '18 at 22:06

2 Answers2

12

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)

Community
  • 1
  • 1
scohe001
  • 15,110
  • 2
  • 31
  • 51
7

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.

Walter
  • 44,150
  • 20
  • 113
  • 196