-1

If a vector contains a bunch of elements that were allocated using new and then dereferenced, is the memory for those elements freed when the vector is deleted? For example:

vector<Obj> a = *(new vector<Obj>());
a.push_back(*(new Obj()));
delete &a;

Is the new Obj that was created deallocated?

Moo-Juice
  • 38,257
  • 10
  • 78
  • 128
Daniel
  • 6,595
  • 9
  • 38
  • 70

5 Answers5

10

This is all going to go horribly wrong. Firstly, the assignment on the first line, "a" is on the stack now (not the heap), and the memory allocated by your new statement is now lost, leaked, gone.

Secondly, re-occurrance of the same situation. Obj() will be constructed, and copied. The memory from your 2nd new lost in the depths of space and time, forever.

Then you try and delete an object allocated on the stack. This is where your program crashes and burns and all that memory loss is inconsequential.

Moo-Juice
  • 38,257
  • 10
  • 78
  • 128
5
vector<Obj> a;
Obj o;
a.push_back(o);

Note: no new or delete in sight. C++ isn't Java.

Pete Becker
  • 74,985
  • 8
  • 76
  • 165
3

No; you seem to be having some trouble with ownership in general. In this declaration:

vector<Obj> a = *(new vector<Obj>());

You are allocating a new vector, copying it, then throwing away the original. Since you no longer have a pointer to it, you cannot delete it. This is called a memory leak. Further, this:

delete &a;

Is undefined behaviour, because you’re not deleting an object allocated via new, but rather a local. What you perhaps meant was this:

vector<Obj*> a;
// ...

That is, allocate a local vector<Obj> named a, whose storage is automatically reclaimed when it goes out of scope.

Now for your actual question, no, the vector only owns the pointers, not the memory to which they point. Consider what would happen otherwise:

vector<Obj*> a;
Obj x;
a.push_back(&x);

If the vector called delete on all its pointer elements, then when a were destroyed (again, automatically), x would also be deleted. Since it was not allocated via new, this is undefined behaviour. Luckily, this is not the case!

If you want a vector of pointers which automatically destroy their referents when the vector is destroyed, use a vector of unique_ptr:

vector<unique_ptr<Obj>> a;
a.push_back(unique_ptr(new Obj()));
Jon Purdy
  • 53,300
  • 8
  • 96
  • 166
  • Pretty solid, except you need `vector a;` in your 4th code snippet if you're going to `push_back()` the *address* of an `Obj` onto it. – j_random_hacker Dec 05 '12 at 20:12
0

No. The *(new Obj()) statement pushes (into the vector) a copy of the heap-allocated object. The copied object (in the vector) is later destroyed (when the vector is destroyed), but the original heap-allocated Obj object is never deleted (and the the heap-allocated memory is never freed).

ChrisW
  • 54,973
  • 13
  • 116
  • 224
0

The vector<Obj> a part allocates an empty vector on the stack.

= *(new vector<Obj>()); Allocates another empty vector on the heap and assigns (copies) it to the stack vector. The memory allocated on the heap has no reference and is leaked.

a.push_back(*(new Obj())); Allocates an Obj on the heap and copies it into the stack vector. The memory allocated on the heap is leaked.

delete &a; Tries to delete the vector allocated on the stack which is an error.

Maybe this is what you're trying to do:

vector<Obj*>* a = new vector<Obj*>();
a.push_back(new Obj());
delete a;

And no, the objects pushed back into the vector will not be deallocated, they will be leaked. When calling delete on the vector pointer a it will default deconstruct the vector which does not involve deallocating dynamically allocated memory.

Tip: Don't use naked pointers, prefer to use unique_ptr or shared_ptr.

Felix Glas
  • 15,065
  • 7
  • 53
  • 82
  • *"And yes, now the data allocated and pushed into the vector should be deleted when you delete the vector."* -- That sentence is a bit ambiguous. It could be read as instructing the OP to call delete on the objects in the vector before calling delete on the vector. But I could also interpret it to mean that calling delete on the vector will result in all the objects being deleted. – Benjamin Lindley Dec 05 '12 at 20:27
  • Hmm, you went the wrong way with that. The allocated objects will *not* be de-allocated, they will be leaked. I thought that was the reason you suggested using smart pointers. – Benjamin Lindley Dec 05 '12 at 21:00
  • Yes you're right. I realise now that the default destructor will only call the destructor on objects, not delete data referenced by pointers. I will correct my answer. – Felix Glas Dec 05 '12 at 21:09