C++ Delete Vector, Objects, Free Memory

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



Leave a reply



Submit