Is Std::Vector Memory Freed Upon a Clear

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

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.

Does std::vector.clear() do delete (free memory) on each element?

No (you need to do the delete yourself at the end as you suggest in your example as the destruction of the bald pointer doesnt do anything). But you can use a boost [or other RAII-based idiom] smart pointer to make it Do The Right Thing (auto_ptr would not work correctly in a container as it has incompatible behaviour under copying etc.), but be sure you understand the pitfalls of such smart pointers before use. (As Benoit mentions, in this case, basic_string is what you're really looking for here.)

Having said that there's a need to understand the pitfalls of smart pointers, having them take care of the memory management implicitly so you dont have to do it explicitly is far less error-prone.

EDIT: Substantially revised to encompass the elements Benoit brought into his far more thorough answer, thanks to strong prodding from the Earwicker and James Matta - thanks for pushing me to do the due diligence on this!

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.

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

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)

How to clear vector in C++ from memory

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

C++ delete vector, objects, free memory

You can call clear, and that will destroy all the objects, but that will not free the memory. Looping through the individual elements will not help either (what action would you even propose to take on the objects?) What you can do is this:

vector<tempObject>().swap(tempVector);

That will create an empty vector with no memory allocated and swap it with tempVector, effectively deallocating the memory.

C++11 also has the function shrink_to_fit, which you could call after the call to clear(), and it would theoretically shrink the capacity to fit the size (which is now 0). This is however, a non-binding request, and your implementation is free to ignore it.

vector string does not clear memory after out of scope

This is a specific of using the top command, not of the std::vector. The issue is that the memory freed by data structures is not released back to the operating system, the level at which the top command monitors memory usage. The memory the OS has given your program remains with your program until the memory manager of C++ decides that it's time to free some memory back to the operating system.

The reason for this is that allocating memory from the operating system is relatively expensive, and it needs to be done in relatively large chunks. The memory manager of the C++ runtime library obtains memory from the OS "wholesale", and then parcels it out to the parts of your program as needed.

If you would like to verify that the memory does indeed get reclaimed, use a tool that monitors memory usage at a lower level, such as valgrind.



Related Topics



Leave a reply



Submit