What Do I Need to Do Before Deleting Elements in a Vector of Pointers to Dynamically Allocated Objects

What do I need to do before deleting elements in a vector of pointers to dynamically allocated objects?

  1. Yes
  2. Vectors are implemented using template memory allocators that take care of the memory management for you, so they are somewhat special. But as a general rule of thumb, you don't have to call delete on variables that aren't declared with the new keyword because of the difference between stack and heap allocation. If stuff is allocated on the heap, it must be deleted (freed) to prevent memory leaks.
  3. No. You explicitly have to call delete myVec[index] as you iterate over all elements.

Ex:

for(int i = 0; i < myVec.size(); ++i)
delete myVec[i];

With that said, if you're planning on storing pointers in a vector, I strongly suggest using boost::ptr_vector which automatically takes care of the deletion.

clearing a vector of pointers

Yes, the code has a memory leak unless you delete the pointers. If the foo class owns the pointers, it is its responsibility to delete them. You should do this before clearing the vector, otherwise you lose the handle to the memory you need to de-allocate.

   for (auto p : v)
{
delete p;
}
v.clear();

You could avoid the memory management issue altogether by using a std::vector of a suitable smart pointer.

How to properly clean up elements from vectors of object pointers

you mentioned in the comments that the objects will have other pointers to them. this sounds like std::shared_ptr<A> to me. this way you can have other pointers to your A objects without memory leaking issues. (std::shared_ptr comes with a small(!) performance cost, but you should not worry about it for now).
additionally i changed your passage to delete/erase your element from the vector. be aware that the A objects are still alive IF there are other instances keeping a std::shared_ptr<A> copy to it (but thats a good thing).

here is the code:

#include <iostream>
#include <vector>
#include <memory>
#include <algorithm>

class A
{
public:
A(int i) { x = i; }
int x;
};

int main()
{
std::vector<std::shared_ptr<A>> Vec;
Vec.emplace_back(std::make_shared<A>(5));
Vec.emplace_back(std::make_shared<A>(4));
Vec.emplace_back(std::make_shared<A>(3));

std::cout << "Size before = " << Vec.size() << std::endl;

Vec.erase(
std::remove_if(std::begin(Vec),std::end(Vec), [](auto&& ptr){ return ptr->x == 3;}),
std::end(Vec));

std::cout << "Size after = " << Vec.size() << std::endl;
for (auto&& a : Vec)
{
std::cout << a->x << std::endl;
}

return 0;
}

If I call delete on a pointer to a vector std::vectorObject**, will the elements be deleted as well?

No, and here's why.

Consider these two cases:

int a, b, c;

auto stackvec = new vector<int*> { &a, &b, &c };
auto heapvec = new vector<int*> { new int, new int, new int };

delete stackvec;
delete heapvec;

If calling delete on the vector*s called delete on the pointers they hold, then you'd be in for a heap of trouble (pun intended) because you'd be deleteing automatic variables with the first delete which yields undefined behaviour (a bad thing).

You have to manually iterate the vector and delete the pointers yourself when you know they're dynamically allocated, or better, use std::unique_ptr and you never need to call delete on anything.

Also, you probably don't need a pointer to a vector in the first place, but I won't judge you since I don't know your situation.

As for std::array and std::vector, you need to know the size of your std::array at compile time and you can't resize it at runtime, but vector has neither of those restrictions.

How do I destruct a dynamically allocated array of dynamic object?

Is it necessary to delete all the objects in the destructor of vector? like this

Technically yes but what if you want a vector of pointers that does not represent ownership? You could easily end up either double-deleting an object, or trying to delete a stack-based object:

obj obj_a;
obj* obj_b = new obj;

vector<obj*> obj_ptrs;
obj_ptrs.elem[0] = &obj_a;
obj_ptrs.elem[1] = &obj_a;
obj_ptrs.elem[2] = obj_b;

delete obj_b;

Whether the pointed objects need to be deleted with the vector is none of the vector's business.

The cleanest way to address that is to use std::unique_ptr, which is an object type that holds a pointer and deletes it when it gets destroyed:

#include <memory>

template <typename T> struct vector {
// ...
~vector() {
// The vector is only responsible for deleting the array.
delete[] elem;
}
};
// ...

void foo() {
vector<std::unique_ptr<obj>> obj_ptrs;

obj_ptrs.elem[0] = std::make_unique<obj>();
obj_ptrs.elem[1] = std::make_unique<obj>();
obj_ptrs.elem[2] = std::make_unique<obj>();

obj stack_obj;

vector<obj*> obj_no_own_ptrs;
obj_no_own_ptrs.elem[0] = obj_ptrs.elem[0].get();
obj_no_own_ptrs.elem[1] = obj_ptrs.elem[0].get();
obj_no_own_ptrs.elem[2] = &stack_obj;

// Everything gets deleted
// No double-delete concern
}

Why vector does not call destructor of pointers on clearing?

Containers only own the elements they directly contain - in this case the pointers. They do not own the pointees of these pointers and are thus not obliged (or even allowed) to destroy them.

You can use a vector of unique_ptrs:

std::vector<std::unique_ptr<foo>> vec;
vec.emplace_back( new foo );

unique_ptrs own their pointees, and thus the vector who contains and owns the unique_ptrs subsequently also owns their pointees, and will destroy them implicitly when destroying the elements (e.g. when going out of scope).

Also have a look at Boosts Pointer Container Library, specifically boost::ptr_vector.

boost::ptr_vector<foo> vec;
vec.push_back( new foo );
// the object is automatically destroyed

How to delete objects from vector of pointers to object?

Only call delete on variables that were created with new
Check this link:
Calling delete on variable allocated on the stack



Related Topics



Leave a reply



Submit