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.
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
Free memory from vector of objects inside a function
You can "submit" a non-binding request to the C++ library std::vector to release its allocated memory by calling shrink_to_fit
after clear
or resize
.
Note this is nonbinding which practically means every sane implementation actually releases memory but you cannot portably rely on this assumption strictly speaking.
I would also strongly suggest replacing the raw pointers in your vector with std::unique_ptr (or even just the objects themselves, if there is no concern of inheritance/slicing). It will ease the visual load of your function and prevent memory leaks in the future.
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!
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).
Should I delete vector string ?
The rule is that when you clear a vector of objects, the destructor of each element will be called. On the other hand, if you have a vector of pointers, vector::clear()
will not call delete
on them, and you have to delete them yourself.
So if all you have is a vector of strings, and not pointers to strings, then your memory leaks must be caused by something else.
Right way to deallocate an std::vector object
The simplest and most reliable way to deallocate a vector is to declare it on the stack and simply do nothing.
void Foo() {
std::vector<int> v;
...
}
C++ guarantees that the destructor of v
will be called when the method executes. The destructor of std::vector
will ensure any memory it allocated is freed. As long as the T
type of the vector<T>
has proper C++ deallocation semantics all will be well.
Best way to delete memory for objects from vector
Your loop is fine, as far as removing and delete
'ing objects (the nullptr
assignment is unnecessary). But the rest of your code is prone to memory leaks. If push_back()
throws, you leak the object you just new
'ed. And you are not delete
'ing the objects that are still in the vector after your loop ends.
Which is the best way to remove element from vector and delete it
The best option is to not use raw pointers at all. Store actual object instances directly in the vector, and let the vector destruct the instances for you when you remove them, and when the vector itself is destructed when it goes out of scope:
int main() {
std::vector<MyObj> objs;
objs.emplace_back(false);
objs.emplace_back(true);
objs.emplace_back(false);
objs.emplace_back(true);
auto itr = objs.begin();
while (itr != objs.end()) {
if (itr->shouldRemove())
itr = objs.erase(itr);
else
++itr;
}
/* alternatively:
objs.erase(
std::remove_if(objs.begin(), objs.end(),
[](auto &o){ return o.shouldRemove(); }),
objs.end()
);
*/
// size will be two
std::cout << "objs.size() :" << objs.size() << std::endl;
return 0;
}
Otherwise, if you need to store pointers to dynamically allocated objects, at least use smart pointers to manage them:
int main() {
std::vector<std::unique_ptr<MyObj>> objs;
objs.push_back(std::unique_ptr<MyObj>(new MyObj(false)));
objs.push_back(std::unique_ptr<MyObj>(new MyObj(true)));
objs.push_back(std::unique_ptr<MyObj>(new MyObj(false)));
objs.push_back(std::unique_ptr<MyObj>(new MyObj(true)));
/* alternatively, if you are using C++14 or later
objs.push_back(std::make_unique<MyObj>(false));
objs.push_back(std::make_unique_ptr<MyObj>(true));
objs.push_back(std::make_unique<MyObj>(false));
objs.push_back(std::make_unique<MyObj>(true));
*/
auto itr = objs.begin();
while (itr != objs.end()) {
if ((*itr)->shouldRemove())
itr = objs.erase(itr);
else
++itr;
}
/* alternatively:
objs.erase(
std::remove_if(objs.begin(), objs.end(),
[](auto &o){ return o->shouldRemove(); }),
objs.end()
);
*/
// size will be two
std::cout << "objs.size() :" << objs.size() << std::endl;
return 0;
}
Proper way to delete and free up memory of a vector (prevent different memory related errors) in c++
Your phrase about memory leaks makes the whole meaning of the question unclear. When the vector goes out of scope, the memory is released. There should be no memory leak.
In major projects, it is fairly common to need a vector to release its allocation at a certain point before it goes out of scope. Failure to do so is not a memory leak but may be a problem. For that purpose, .clear()
is useless. The swap
approach you suggested (without the .clear
) works. I don't know a way to do it without swap
.
Related Topics
Why Is Padding Added for Multiple Data Members of Structures and Not for Single Members
Find Out If String Ends with Another String in C++
C++ High Precision Time Measurement in Windows
Regex Replace with Callback in C++11
Unnecessary Curly Braces in C++
How to Force a Static Member to Be Initialized
One VS2010 Bug ? Allowing Binding Non-Const Reference to Rvalue Without Even a Warning
When Do Extra Parentheses Have an Effect, Other Than on Operator Precedence
Find Argc and Argv from a Library
Windows 7 Timing Functions - How to Use Getsystemtimeadjustment Correctly
Is It Worth Setting Pointers to Null in a Destructor
What Is Shared_Ptr's Aliasing Constructor For
How to Initialize a Const Field in Constructor
"Undefined Reference To" Using 'G++' to Compile a C++ Program