Question

So, I have dynamically assigned memory to a 2D array:

int **paMatrix = new int*[r];

for(int i=0; i<r; i++)
    paMatrix[i] = new int[c];

Assume that my code has already defined r and c. Now I want to free the memory again. If paMatrix was single-indexed, the delete[] paMatrix; would be enough. Is it also enough in this case, or do I have to write

for(int i=0; i<r; i++)
    delete[] paMatrix[i];

delete[] paMatrix;

In case I need to call delete once for each new statement, is there a way to rewrite my code so that I only need a single delete statement?

Was it helpful?

Solution

In general, you need to match every new with a delete so if, as here, you're juggling a whole array of raw pointers, you will indeed need to delete each in turn.

This can be a serious hassle if the code between new and delete isn't straightforward, and almost impossible to ensure if it might throw exceptions. For that reason, you should always use RAII types such as containers and smart pointers to manage dynamic resources. In this case, vector<vector<int>> might be an appropriate choice.

I guess the real question is "What does delete and delete[] really do behind the scene?"

If the object type has a non-trivial destructor, it calls that destructor on each object before deallocating the memory. Thus RAII types will automatically release whatever resource they manage through their destructor; but raw pointers don't have destructors, so deleting them will not free any memory that they point to.

OTHER TIPS

As said, in c++ one rarely has more then one indirection through pointers. In a matter of fact, in c++ pointers are avoided whenever possible.

In case I need to call delete once for each new statement, is there a way to rewrite my code so that I only need a single delete statement?

One way would be :

int *paMatrix = new int[r*c];

but then you need to play with indexes.

Another solution (without pointers) without even one delete statement is to use std::vector :

std::vector< std::vector< int > > paMatrix( r, std::vector< int >( c, 0 ) );

You need

for(int i=0; i<r; i++)
    delete[] paMatrix[i];

delete[] paMatrix;

There's no way around, except smart pointers etc.

As described in the other answers here, you need to match calls to new with calls to delete.

However if you were willing to change your conception of a 2d array, you can simplify it considerably. For example if it truly a matrix of r x c size you could allocate it as a single array of r*c in size:

int* paMatrix = new int[r*c];

Then you would be able to delete it in a single step.

The tradeoff would be having to index the array using something like paArray[x+c*y] instead of the more natural paArray[x][y].

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top