pen pen - 2 months ago 10
C++ Question

What is the proper way to delete a dynamic array?

I created a 3D array

t
dynamically (
t
is of type
int***
). Now I am trying to delete it.

I have come across 2 suggestions:
One is that simply do

delete[] t;


and apparently, it will delete everything.

The other is to do something like

for(int i=0;i<3;i++)
{
for(int j=0;j<t1[i];j++)
{
delete[] t[i][j];//delete all 1D array
}
delete[] t[i];//delete all 2D array
}
delete[] t;//delete the 3D array


(
t1
stores the size of
t[i]
and
t2
the size of
t[i][j]
)

what is the best way?

Answer

As @aschepler mentions in the comments, this depends on how the memory was initially allocated. I assume that you probably allocated the memory like this:

int*** t = new int**[dim1];
for (int i = 0; i < dim1; i++) {
   t[i] = new int*[dim2];
   for (int j = 0; j < dim2; j++) {
      t[i][j] = new int[dim3];
   }
}

If you allocated memory in this way, then the memory looks something like this:

                      [ 0 ] --> [ 0 ][ 1 ][ 2 ][ 3 ]
                +---> [ 1 ] --> [ 0 ][ 1 ][ 2 ][ 3 ]
                |     [ 2 ] --> [ 0 ][ 1 ][ 2 ][ 3 ]
                |
 t ---> [ 0 ] [ 1 ]
          |
          |     [ 0 ] --> [ 0 ][ 1 ][ 2 ][ 3 ]
          +---> [ 1 ] --> [ 0 ][ 1 ][ 2 ][ 3 ]
                [ 2 ] --> [ 0 ][ 1 ][ 2 ][ 3 ]

Now, suppose that you just write

delete[] t;

If you do this, then memory will look like this:

                      [ 0 ] --> [ 0 ][ 1 ][ 2 ][ 3 ]
                      [ 1 ] --> [ 0 ][ 1 ][ 2 ][ 3 ]
                      [ 2 ] --> [ 0 ][ 1 ][ 2 ][ 3 ]

 t ---> xxx

                [ 0 ] --> [ 0 ][ 1 ][ 2 ][ 3 ]
                [ 1 ] --> [ 0 ][ 1 ][ 2 ][ 3 ]
                [ 2 ] --> [ 0 ][ 1 ][ 2 ][ 3 ]

In other words, you've reclaimed one of the arrays, but you've leaked the majority of the memory. Oops!

On the other hand, if you use the for-loop version of the deletion code, you end up reclaiming all the memory because you've gone through all of the pointers and freed each array allocated.

Generally speaking, every allocation should have a matching deallocation, so if you called new[] several times, you'll need to call delete[] an equal number of times.

As some of the comments have pointed out, there are probably better ways for you to manage a 3D array than to use an int ***. The general trend in C++ is to use objects to automatically manage memory as much as possible. Consider looking into the Boost multi_array type, or consider writing a wrapper around a std::vector that stores the entries in row-major order.