Reputation: 15
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?
Upvotes: 1
Views: 8674
Reputation: 3911
it's so important to unallocate memory properly as much as allocating it. we should be so cautious while creating a multi-dim array on the heap as much as while deleting it:
#include <iostream>
using std::cout;
using std::endl;
int main()
{
int*** ptrInt = new int**[3];
for(int i(0); i < 3; i++)
ptrInt[i] = new int*[3];
for(int i = 0; i < 3; i++)
{
for(int j(0); j < 3; j++)
ptrInt[i][j] = new int[3];
}
for(int i = 0; i < 3; i++)
{
for(int j(0); j < 3; j++)
for(int k(0); k < 3; k++)
ptrInt[i][j][k] = k;
}
for(int i = 0; i < 3; i++)
{
for(int j(0); j < 3; j++)
for(int k(0); k < 3; k++)
cout << "ptrInt[" << i << "][" << j << "][" << k << "]: " << ptrInt[i][j][k] << endl;
}
// now freeing memory:
for(int i = 0; i < 3; i++)
{
for(int j(0); j < 3; j++)
delete[] ptrInt[i][j];
delete[] ptrInt[i];
}
delete[] ptrInt;
ptrInt = NULL; // if we call delete again on a null pointer it's ok
cout << endl;
return 0;
}
Upvotes: 0
Reputation: 372814
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.
Upvotes: 6