Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

std

Consider this code:

#include <vector>  void Example() {     std::vector<TCHAR*> list;     TCHAR* pLine = new TCHAR[20];     list.push_back(pLine);     list.clear();    // is delete called here?     // is delete pLine; necessary? } 

Does list.clear() call delete on each element? I.e. do I have to free the memory before / after list.clear()?

like image 877
Ignas Limanauskas Avatar asked Feb 27 '09 09:02

Ignas Limanauskas


People also ask

Does vector clear free memory?

No, memory are not freed. In C++11, you can use the shrink_to_fit method for force the vector to free memory. You can use it, but the standard specifies that it does not force extra memory to be released (§23.3.

What does vector Clear () do?

vector::clear() clear() function is used to remove all the elements of the vector container, thus making it size 0.

Does std::vector clear call Delete?

So what your question should be: "Does std::vector<T*>::clear() call delete on its elements?" and here the answer is: No, it does not call delete . You have to do it manually like shown in your example code, or you can (and probably should) use objects like std::string or smart pointers instead of raw pointers.

Does vector automatically deallocate memory?

std::vector will not automatically de-allocate the memory, so your program will leak.


2 Answers

std::vector does call the destructor of every element it contains when clear() is called. In your particular case, it destroys the pointer but the objects remain.

Smart pointers are the right way to go, but be careful. auto_ptr cannot be used in std containers. boost::scoped_ptr can't either. boost::shared_ptr can, but it won't work in your case because you don't have a pointer to an object, you are actually using an array. So the solution to your problem is to use boost::shared_array.

But I suggest you use std::basic_string<TCHAR> instead, where you won't have to deal with memory management, while still getting the benefits of working with a string.

like image 75
Benoît Avatar answered Sep 19 '22 10:09

Benoît


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!

like image 32
Ruben Bartelink Avatar answered Sep 21 '22 10:09

Ruben Bartelink