When you create an array with new SomeType[M]
you must use delete []
to free the memory allocated to the array.
In the case of 2D arrays as you have written, you create an array of pointers first. Let's call this the "outer array". Then for each element in the outer array you create another array again with new SomeType[N]
. The return of new SomeType[N]
is a pointer, which will point to the corresponding "inner array".
In order to free all the memory in your "2D array" you need to first call delete []
for each inner array and only after that you call delete []
for the outer array. Not doing any of these will result in a memory leak.
In you example you don't have any delete command and thus we know for sure that there is a memory leak. Let's pretend we don't know this and check with valgrind. If we ran the executable with valgrind passing 2 and 3 as the inputs for the size, then valgrind returns something like
==194743==
==194743== HEAP SUMMARY:
==194743== in use at exit: 40 bytes in 3 blocks
==194743== total heap usage: 6 allocs, 3 frees, 74,792 bytes allocated
==194743==
==194743== LEAK SUMMARY:
==194743== definitely lost: 16 bytes in 1 blocks
==194743== indirectly lost: 24 bytes in 2 blocks
==194743== possibly lost: 0 bytes in 0 blocks
==194743== still reachable: 0 bytes in 0 blocks
==194743== suppressed: 0 bytes in 0 blocks
==194743== Rerun with --leak-check=full to see details of leaked memory
==194743==
==194743== For lists of detected and suppressed errors, rerun with: -s
==194743== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
The leak summary from valgrind clearly tells us that some memory was not properly freed.
Now, add the following code to the end of your main function to properly free all that memory
// Free all the inner arrays. Notice that we call `delete []` passing the
// pointer of an inner array
for ( i = 0; i < M; i++) {
delete [] matrix[i];
}
// Delete the outer array. Notice that now we pass the pointer of the outer array
delete [] matrix;
If we ran this with valgrind again we get something like
==197046==
==197046== HEAP SUMMARY:
==197046== in use at exit: 0 bytes in 0 blocks
==197046== total heap usage: 6 allocs, 6 frees, 74,792 bytes allocated
==197046==
==197046== All heap blocks were freed -- no leaks are possible
==197046==
==197046== For lists of detected and suppressed errors, rerun with: -s
==197046== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Valgrind is now telling us that we have indeed freed all the memory we have dynamic allocated.
All heap blocks were freed -- no leaks are possible