C++ Memory Manament: How to release memory for an array of pointers?
Q: How to release memory for an array of pointers?
A: Consider the following code:
Code:
byte rows = 3;
byte cols = 3;
byte **array = new byte*[rows];
for(int i=0; i < rows; i++)
{
array[i] = new byte[i+1];
}
delete [] array;
This code generate memory leaks while running. Why? Because you are not freeing all the allocated memory.
The short answer is that 'array' is an array of pointers, with each of it's elements pointing to a separate memory block, so you first have to free these block before freeing the array that holds the pointers.
The long answer will show you step by step what you are doing wrong.
In this line
Code:
byte **array = new byte*[rows];
you are allocating space for 'rows' (=3) elements. The variable 'array' is located on the stack, and it points towards a memory block from the heap. If you look into the memory with the debugger, you'll see array points to this block, starting at '0x009A4AD0' in this example (which is fenced with some special bytes in a debug built for detecting out of bounds accesses; see Inside CRT: Debug Heap Management).
Code:
009A4ACC FD FD FD FD
009A4AD0 CD CD CD CD
009A4AD4 CD CD CD CD
009A4AD8 CD CD CD CD
009A4ADC FD FD FD FD
At this point the array's elements are not initialized, thus they have the '0xCDCDCDCD' value. Going further into the for statement, at first iteration, you allocate a new memory block on the heap, and a pointer to the first address of that block is stored in the first element of the array:
Code:
009A4ACC FD FD FD FD
009A4AD0 18 4B 9A 00
009A4AD4 CD CD CD CD
009A4AD8 CD CD CD CD
009A4ADC FD FD FD FD
Pointer '0x009A4B18' points to a memory area from the heap:
Code:
009A4B14 FD FD FD FD
009A4B18 CD FD FD FD
009A4B1C FD F0 AD BA
which contains a single byte (fenced with guarding bytes).
Similar things happen after the second and the third iterations. At the end of the for statement, your array looks like this:
Notice that these values can be different each time you run the program.
So you have successfully allocated 1 + 2 + 3 = 6 bytes in three different memory blocks on the heap, plus the memory necessary to hold the pointers to those 6 bytes.
When you do this:
Code:
delete [] array;
you are only freeing this memory holding the 3 pointers, not the memory they point to. So in your debugger's window you will see a dump like this:
Detected memory leaks!
Dumping objects ->
D:\Teste\test.cpp(104) : {65} normal block at 0x009A4BA8, 3 bytes long.
Data: < > CD CD CD
D:\Teste\test.cpp (104) : {64} normal block at 0x009A4B60, 2 bytes long.
Data: < > CD CD
D:\Teste\test.cpp (104) : {63} normal block at 0x009A4B18, 1 bytes long.
Data: < > CD
Object dump complete.
If you compare the address of the leaked blocks with the elements of the arrays you can see they are, obviously, the same.
To make sure memory is freed correctly, you must free those blocks first:
* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.