CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 1 of 1
  1. #1
    Join Date
    Oct 2002
    Location
    Timisoara, Romania
    Posts
    14,360

    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:

    Code:
    009A4ACC  FD FD FD FD
    009A4AD0  18 4B 9A 00
    009A4AD4  60 4B 9A 00
    009A4AD8  A8 4B 9A 00
    009A4ADC  FD FD FD FD
    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:

    Code:
    for(i=0; i < rows; i++)
    {
      delete [] array[i];
    }
    
    delete [] array;
    Attached Images Attached Images  
    Last edited by cilu; November 15th, 2005 at 06:21 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured