views:

164

answers:

3
vector< int > vect;
int *int_ptr = new int(10);
vect.push_back( *int_ptr );

I under stand that every "new" needs to be followed by a "delete" at some point but does the clear() method clean this memory?

What about this method of doing the same thing:

vector< int > vect;
int int_var = 10;
vect.push_back( int_var );

From what I understand, clear() calls the variables destructors, but both vect.push_back() methods in this example push an object on the vector, not a pointer. so does the first example using an int pointer need something other than clear() to clean up memory?

+5  A: 

The first method leaks because the vector never takes ownership of the allocated pointer. In fact, it doesn't contain a pointer at all, only a copy of the value.

The second method does not leak, as no memory is dynamically allocated (except internally in the vector -- it will handle that memory itself).

Fred Larson
when you say it will handle the memory itself, you mean after i call a vector.clear()?
TheFuzz
The memory will be recovered when the vector is destroyed. `clear()` will not actually deallocate any memory; the vector will retain the capacity in case it needs to grow again later.
Fred Larson
So what is stopping me from not using pointers at all and simply creating temp stack variables then pushing them onto the vector when i need to? for some reason pointers lost their point.
TheFuzz
It's entirely possible (even likely) that you don't need pointers at all. Dynamic allocation is normally needed only when the object's lifetime needs to exceed the lifetime of the scope where the object is created.
Fred Larson
i must ask, you said memory is recovered when the vector is destroyed, so when the whole vector goes out of scope ( or a pointer to a vector is deleted ) everything inside will be deleted given the memory inside the vector wasn't dynamically allocated?
TheFuzz
Correct. Everything the vector allocated will be deallocated.
Fred Larson
+5  A: 

When you push_back on a vector, you add a copy of the data to the vector. Therefore, in both cases, the original data still needs to be freed. In the first case, you need to delete it; in the second, it will be "freed" by the stack pointer as it goes out of scope.

Dave
+1  A: 

Vectors make copies on push_back. Since a pointer is 'just another variable' (but one that happens to point to memory), when you push_back an integer pointer that has been previously allocated, you copy the pointer's value into the vector, causing a potential dangling pointer, since there will be two pointers pointing at the same spot in memory.

In your first example, you would need to delete the memory manually. One strategy I've used in the past for meddling with graph classes is to have something like this (vast amounts of stuff redacted due to being at work and typing quickly):

class graph //quick-format
{
vector<node*> nodes;
add_node(node n)
{
  node *temp = new node; 
  *temp = n; 
  nodes.push_back(temp) 
}
~graph()
{ 
   for(int i = 0; i < nodes.size(); i++) 
      delete nodes[i]; 
}
};

As a caveat, graph's copy semantics will have to be examined. As it stands, it will result in deleting previously-free'd memory. The advantage is that you can always have the same set of nodes hanging around. Caveat Emptor, like any direct memory usage..

However, if you simply push a non-pointer variable, there is no possibility of memory leaking from your end. Possibly the vector will leak, but... that is practically impossible at this point in the maturity of the tools.

Paul Nathan