68

Suppose I have a std::vector of structs. What happens to the memory if the vector is clear()'d?

std::vector<myStruct> vecs;
vecs.resize(10000);
vecs.clear();

Will the memory be freed, or still attached to the vecs variable as a reusable buffer?

Amir
  • 10,600
  • 9
  • 48
  • 75
  • Thanks everyone. I want the memory to be freed - guaranteed. So I allocate the vector using new std:vector, then call delete when I'm done. Thus memory guaranteed to be freed. –  Dec 19 '12 at 03:20
  • 4
    @AndrewS.: the only effect of the dynamic allocation is to introduce an ineffiency. see jerry's answer for a reasonable way to empty a vector. in a loop body another good way is to just make the vector local to the loop body, i.e. declare it inside the loop body. – Cheers and hth. - Alf Dec 19 '12 at 04:16
  • Just for interest, why does the memory need to be guaranteed free? – deworde Dec 19 '12 at 09:08
  • Because this is ios operation and I am trying to be economical with memory on the more limited platform. –  Dec 19 '12 at 18:57

5 Answers5

78

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

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • For me it does not work. I have a vector of structure and an image is a element of structure. By doing `shrink_to_fit` it does not release GPU or RAM. – BarzanHayati Sep 18 '22 at 05:19
38

The vector's memory is not guaranteed to be cleared. You cannot safely access the elements after a clear. To make sure the memory is deallocated Scott Meyers advised to do this:

vector<myStruct>().swap( vecs );

Cplusplus.com has the following to say on this:

Removes all elements from the vector, calling their respective destructors, leaving the container with a size of 0.

The vector capacity does not change, and no reallocations happen due to calling this function. A typical alternative that forces a reallocation is to use swap:...

Luc Touraille
  • 79,925
  • 15
  • 92
  • 137
Alexander Chertov
  • 2,070
  • 13
  • 16
10

The destructor is called on the objects, but the memory remains allocated.

Ryan Guthrie
  • 688
  • 3
  • 11
7

No, memory are not freed.

In C++11, you can use the shrink_to_fit method for force the vector to free memory.

http://www.cplusplus.com/reference/vector/vector/

BAK
  • 972
  • 8
  • 23
  • 4
    You can use it, but the standard specifies that it does *not* force extra memory to be released (§23.3.6.3/6): "shrink_to_fit is a non-binding request to reduce capacity() to size()." – Jerry Coffin Dec 19 '12 at 03:08
  • 1
    ... and thus, it's about as good as `resize(0)` which *might* have the side effect of releasing the memory – Marcus Müller Aug 20 '17 at 15:06
  • 8
    No, `resize(0)` is [guaranteed to keep the memory](http://en.cppreference.com/w/cpp/container/vector/resize). – Davis Herring Sep 20 '17 at 00:55
  • resize(0) has better not have that side effect! What a terrible decision it would be leaving that up to chance. – Matthew M. Dec 10 '21 at 15:45
3

.resize(0) and .clear() don't release or reallocate allocated memory, they just resize vector to zero size, leaving capacity same.

If we need to clear with freeing (releasing) memory following works:

Try it online!

v = std::vector<T>();

It calls && overload of = operator, which does moving, similar behaviour as with swap() solution.

This assignment technique works when there is && overload of = operator, and it'is guaranteed to be present in all C++11 STD libraries, see here. So if you compile with -std=c++11 (gcc/clang) or /std:c++11 (msvc) switch (or later) my solution is guaranteed to work.

Arty
  • 14,883
  • 6
  • 36
  • 69
  • but the question is really _is it **required** to?_ not just does it happen to with this code, compiler, settings, etc. why would Meyers et al recommend `swap()` if assigning would suffice? – underscore_d Jul 15 '21 at 20:05
  • 1
    @underscore_d Yes, my assigning code clears and releases memory always with recent compilers. Probably Meyers used `swap()` because his book was quite old, when there was no `&&` rvalue reference. Because my assignment wouldn't work when there is no `&&` overload of `=` operator, and this overload presents already everywhere in all STD libraries for quite many last years. `&&` is guaranteed to be present in all C++11 STD libraries, [see here](https://en.cppreference.com/w/cpp/container/vector/operator%3D). – Arty Jul 16 '21 at 03:01