15

I'm new to C++ so this may be a newbie question however I'm not entirely clear how to clear it from memory. I've searched online and looked are several answers but was unclear on how to properly execute what im trying to do.

How can i clear my vector from memory correctly in c++? Thanks and i apologize if this is a dup post.

vector<ElementData> Elements;

As mentioned by a comment below, i would like to return the memory used as well.

except that it will not return any memory to the system as the capacity remains unchanged.

JokerMartini
  • 5,674
  • 9
  • 83
  • 193

6 Answers6

25

If you want to reset you vector back to a empty state then we can use the swap trick to swap the contents of the vector into a temporary that will get destroyed and free the memory

vector<ElementData> Elements
// fill the vector up
vector<ElementData>().swap(Elements);

This will create a temporary empty vector, swap it with the one you have so now it is empty and then destroy everything in the temporary vector.

You can see it working in this little example

int main() {
    std::vector<int> foo(500);
    std::cout << foo.capacity() << std::endl;
    std::vector<int>().swap(foo);
    std::cout << foo.capacity() << std::endl;
}       

Live Example

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
  • thank you for your help. – JokerMartini Feb 19 '16 at 21:08
  • 3
    Why not just `Elements = vector();`? – Christian Hackl Feb 19 '16 at 22:52
  • 2
    @ChristianHackl That should work but I worry that the vector would still be able to keep its capacity. I am not sure what the standard has to say about that. – NathanOliver Feb 20 '16 at 00:05
  • @NathanOliver I understand that the inverse swap operation, such as `Elements.swap(vector())` should be semantically equivalent to `vector().swap(Elements)`, right? – ABu Jan 27 '22 at 16:22
  • 1
    @Peregring-lk `Elements.swap(vector())` wont work because `swap` has a `vector &` parameter, so it cannot bind to the temporary `vector()` creates. – NathanOliver Jan 27 '22 at 16:37
  • @NathanOliver right, haven't thought of that. Do you know if there is any reason why swap doesn't accept a rvalue-reference? That would allow that pattern. Writting the temporary as argument is more descriptive in my opinion. – ABu Jan 27 '22 at 16:45
  • 2
    @Peregring-lk No I do not. FWIW, Making a function like `template void clear_vector_memory(std::vector& vec) { vector().swap(vec); }` might be even better. That way your code just becomes `clear_vector_memory(my_vector);` – NathanOliver Jan 27 '22 at 16:54
16

std::vector variables are normally destructed automatically when you go out of scope, or when the class object they are members of are destroyed. The destructor of std::vector also destroys all elements in the vector.

To completely clear a vector explicitly, first clear the vector (destroy the elements)

v.clear()

then return the memory previously reserved for the vector elements

v.shrink_to_fit();

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

Only call shrink_to_fit if it's likely that the vector previously contained far more elements than you are going to fill it with.

Johan Lundberg
  • 26,184
  • 12
  • 71
  • 97
  • FYI `shrink_to_fit` is not required to do anything so it may or may not work. – NathanOliver Feb 19 '16 at 21:16
  • 3
    Yes, but allocations are not observable under the as-if rule, so it would be hard for the standard to have a stronger wording. I'm not aware of any C++11 compliant compiler with a no op shrink_to_fit. VS and gcc have ´real´ ones for sure. – Johan Lundberg Feb 19 '16 at 21:20
3

When your program ends, vector's dtor will get called and delete your vector for you, since you've allocated it on the stack. Furthermore, the dtor for ElementData will get called for each one in the vector.

Chara
  • 1,045
  • 10
  • 21
1

In most cases, the best way is to limit the scope of the vector to where it's actually needed. So, instead of something like:

vector<Elements> Elements;
... do some work with Elements ...
Elements.clear(); // or whatever "trick" you want to use
... do more work where Elements is not needed ...

You would do this:

{ // begin a new scope
    vector<Elements> Elements;
    ... do some work with Elements ...
} // Elements is now out of scope, its memory has been freed
... do more work where Elements is not needed ...

The other benefit of this is that after Elements has gone out of scope, you can't accidentally reuse it. If the function is small, you probably don't need to create a new explicit scope. Returning from the function will have the same effect.

Ferruccio
  • 98,941
  • 38
  • 226
  • 299
0

You don't have to do anything special. Since both the vector and the elements inside are statically allocated (i.e. not created by new), when the vector gets out of scope, it's deallocated and the destructor gets called on all ElementData inside. If you would have vector<ElementData*>, where the vector only contains pointers to ElementData, then you would also have to delete all the ElementData yourself.

Oskar Hýbl
  • 401
  • 3
  • 9
-5

Elements.clear() will do what you want.

Here are the rest of the functions available to vectors.

Alex
  • 14,973
  • 13
  • 59
  • 94