kathy posted:
If I have 2D array like:
int **p;
p = new int*[10];
for(int i=0;i<10;i++)
{
p[i] = new int[10];
}
To delete the p, should I use:
for(int i=0;i<10;i++)
{
delete p[i];
}
delete p;
or just:
delete p;
This shows you haven't got a firm understanding of what's going on. I'll try
give you a hand.
Think of a 16-Bit unsigned integer. It looks like the following in memory:
0000 0000 0000 0000
Now think of an "int *". A pointer variable is just like any other variable
-- i.e. it stores data as bits in memory. An "int" variable stores an
itegral value in memory, while an "int*" variable store a memory address
value in memory. On a particular system, a memory address may be 16 bits. So
let's say you define a pointer variable as follows:
int* p = 0;
It will look like this in memory:
0000 0000 0000 0000
If you wanted to give it the memory address, 82, it would look like so in
memory:
0000 0000 0101 0010 (This is the binary value for 82)
If you define an array of pointers, like so:
int* p[3] = {0, 0, 0};
Then they'll be one after the other in memory like this:
----------1st------- ---------2nd-------- ---------3rd--------
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
Let's analyse your code.
Line 1: int **p;
Line 2:
Line 3: p = new int*[10];
Line 1 defines a pointer variable. A pointer variable stores a memory
address. Let's say it's 16 bits on this system. As of yet it has no value
stored in it.
Line 3 is an assignment statement. It takes what you have on the right and
stores it in the variable on the left. On the right hand side, you're
dynamically allocating ten "int *" variables. Think of "new" as a function
that returns a memory address; it returns the address of the memory which it
has allocated. The "new" statement will allocate ten "int"'s somewhere, like
so:
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000
Then "new" will return the memory address of the first "int*". Let's say
that this memory address is 82. At the end of this assignment statement,
"p" has the value of 82.
When you call "delete", this memory will then be deallocated. All memory
which you allocate should eventually be deallocated, like so:
Line 1: int **p;
Line 2: p = new int*[10];
Line 3: delete [] p;
Note that the value of "p", i.e. 82, has been passed to "delete". Because of
this, "delete" knows which memory to deallocate.
Now let's look at your particular example:
int **p;
p = new int*[10];
for( int i=0; i<10; i++ )
{
p[i] = new int[10];
}
"p" will still have the value of 82. In the code above, you're storing a
memory address in each of the ten pointers. What memory address have you
given them... ? Memory addresses which correspond to newly allocated arrays
of ten integers. As we saw previously, you eventually have to pass the
memory addresses to "delete" so that the memory becomes deallocated. In your
loop, you allocate an array of ten integers. The loop runs 10 times, so
you've allocated ten arrays of ten integers. (Read the previous sentence
again). Therefore you've to call "delete" for each of the ten arrays which
you've allocated. Thus you have to do this:
int **p;
p = new int*[10]; //Allocate once
for( std::size_t i = 0 ; i < 10; ++i )
{
p[i] = new int[10];
//Allocate ten times
}
for( std::size_t i = 0 ; i < 10; ++i )
{
delete [] p[i];
//Deallocate ten times by passing
//it the memory addresses.
}
delete [] p; //Deallocate once
Just remember that a pointer variable stores a number which is a memory
address. If you don't keep note of this number, then you've nothing to pass
to "delete", and then you'll never be able to deallocate the memory you
allocated.
Hypothetically speaking, if you did the following:
int **p;
p = new int*[10]; //Allocate once
for( std::size_t i = 0 ; i < 10; ++i )
{
p[i] = new int[10];
//Allocate ten times
}
delete [] p; //Deallocate once
Then you will be deallocating the original array which you declared, but you
*won't* be deallocating the ten arrays which you declared with your loop.
-Tomás