Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Memory allocation question involving vectors

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?

like image 450
TheFuzz Avatar asked May 07 '10 20:05

TheFuzz


People also ask

How does a vector allocate memory?

Vectors are assigned memory in blocks of contiguous locations. When the memory allocated for the vector falls short of storing new elements, a new memory block is allocated to vector and all elements are copied from the old location to the new location. This reallocation of elements helps vectors to grow when required.

Do vectors dynamically allocate memory?

Arrays have to be deallocated explicitly if defined dynamically whereas vectors are automatically de-allocated from heap memory.

Does std::vector use heap?

As mentioned above, std::vector is a templated class that represents dynamic arrays. std::vector typically allocates memory on the heap (unless you override this behavior with your own allocator). The std::vector class abstracts memory management, as it grows and shrinks automatically if elements are added or removed.

Do vectors cause memory leaks?

std::vector does not cause memory leaks, careless programmers do. You should also include an example that actually exhibits the behavior you are experiencing, including calls to the CRT debug API. There's a good possibility that you're incorrectly interpreting the leaks based on when they are reported.


3 Answers

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).

like image 54
Fred Larson Avatar answered Oct 02 '22 14:10

Fred Larson


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.

like image 45
Dave Avatar answered Oct 02 '22 13:10

Dave


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.

like image 34
Paul Nathan Avatar answered Oct 02 '22 14:10

Paul Nathan