question

FethullahSPAHOLU-3659 avatar image
0 Votes"
FethullahSPAHOLU-3659 asked FethullahSPAHOLU-3659 commented

delete array of pointer

Hi,

Can one of you ( pls only experts) explain which one is true first or second? Because we know that in the background processer, there is no 2D, 3D, 4D... dimension for the memory. That is after we want to create one 2D or 3D dimensional array, it is allocated 1D consecutively array in the memory. Pls, do not say you have to deallocate for each element of the array. Can you explain why the first terms are wrong as core (including memory)? Because we do not get any error for the first terms on the compiler. Pls, proof. Thx.


First:

 int main()
 {
     int **container = new int*[n];
     for(int i = 0; i < n; ++i)
         container[i] = new int[size];
    
     // ... and to deallocate...
     delete [] container;
 }



Second:
int main()
{
int **container = new int*[n];
for(int i = 0; i < n; ++i)
container[i] = new int[size];

     // ... and to deallocate...
     for(int i = 0; i < n; ++i)
         delete [] container[i];
    
     delete [] container;
 }



c++
· 4
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.


I think that the number of delete must correspond to the number of new.


0 Votes 0 ·

It's simple, really - for every new, there should be a corresponding delete. You are calling new n+1 times, so you should call delete n+1 times, or else you leak memory.

0 Votes 0 ·

You are not allocating a 2D array - you are making n+1 separate allocations, completely unrelated to each other as far as the compiler can tell. It is possible - in fact, likely - that they will not be consecutive in memory.

Consider:

 int **container1 = new int*[n];
 int **container2 = new int*[n];
 for (int i = 0; i < n; ++i) {
   container1[i] = new int[size];
   container2[i] = new int[size];
 }

Would you expect that delete[] container1 would somehow know to free every other new int[size] allocation? Or that the loop would somehow produce two consecutive blocks of memory, with odd-numbered allocations going to the first one and even-numbered allocations to the second, based only on where the pointer is assigned to after the allocation is performed?

0 Votes 0 ·

Consider a simple example for your first example. Assume n is 2, size is 3, and pointers and int are both 4 bytes.

After line 3, container points to an area capable of holding two int*: 0x1000 through 0x1007 for example.

After the first execution of line 5, container[0] point to an area capable of holding three int: 0x2000 through 0x200b for example

After the second execution of line 5, container[1] ... 0x3000 through 0x300b.

After line 8, the value of container is indeterminate and the memory from 0x1000 through 0x1007 has been released. While container[0] and container[1] no longer exist, the memory at 0x2000 through 0x200b and 0x3000 through 0x300b is still allocated. Since there are no pointers to that memory, it can never be release or used for any purpose. That memory will remain unavailable for the life of your program. This situation is called a memory leak.

You should have no trouble understanding why the second example eliminates this problem.

0 Votes 0 ·

1 Answer

RLWA32-6355 avatar image
0 Votes"
RLWA32-6355 answered FethullahSPAHOLU-3659 commented

The first example results in a memory leak -

Try this to see the leak in a debug build -

 #ifdef _DEBUG
 #define _CRTDBG_MAP_ALLOC
 #include <stdlib.h>
 #include <crtdbg.h>
 #define _ATL_DISABLE_NOTHROW_NEW
 #ifndef DBG_NEW
 #define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ )
 //#define new DBG_NEW
 #endif
 #else
 #include <stdlib.h>
 #endif  // _DEBUG
    
    
 int main()
 {
     constexpr int size{ 50 }, n{ 10 };
     _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
    
     int** container = DBG_NEW int* [n];
     for (int i = 0; i < n; ++i)
         container[i] = DBG_NEW int[size];
    
     // ... and to deallocate...
    
     // Uncomment to fix memory leak
     // 
     //for (int i = 0; i < n; ++i)
     //    delete[] container[i];
    
     delete[] container;
 }

Output pane leak report after program terminates -

124648-leak.png



leak.png (49.9 KiB)
· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

To review some documentation on the method of leak
detection illustrated by RLWA32 see:

Find memory leaks with the CRT library
https://docs.microsoft.com/en-us/visualstudio/debugger/finding-memory-leaks-using-the-crt-library?view=vs-2019

  • Wayne

1 Vote 1 ·

Thank you so much!

0 Votes 0 ·