1

This is some code I wrote just to understand working with pointers. Here I want to allocate and display a 2-dimensional Pointerarray

int main()
{
    constexpr int size = 10;
    int** _2darray = new int* [size];

    for ( int i = 0; i < size; i++ )
    {
        *(_2darray + i) = new int[i];
        for ( int j = 0; j <= i; j++ )
        {
            *(*(_2darray + i) + j) = j;
        }
    }

    for ( int i = 0; i < size; i++ )
    {
        for ( int j = 0; j <= i; j++ )
        {
            std::cout << _2darray[i][j] << " ";
        }
        std::cout << std::endl;
    }
}

This will result in printing this:

0
0 1
0 1 2
0 1 2 3
0 1 2 3 4
0 1 2 3 4 5
0 1 2 3 4 5 6
0 1 2 3 4 5 6 7
0 1 2 3 4 5 6 7 8
0 1 2 3 4 5 6 7 8 9

But if I want to prevent a memory leak now, I would want to do this:

for ( int i = 0; i < size; i++ )
  {
       delete[] _2darray[i];
  }
  delete[] _2darray;

Unfortunately this will give me an exception that the heap was corrupted

enter image description here

I guess that it crashes because it doesen't know the exact size of the subarrays, but I also heard that delete always keeps track of how much bytes are being allocated for a array.

Thank you for any short answer.

user4581301
  • 29,019
  • 5
  • 26
  • 45
sigmund
  • 41
  • 6
  • 1
    The delete logic is correct. Unfortunately sometime after creating the arrays and before deleting them the program marches out of bounds and corrupts some important book-keeping information stored near the array. Find where that happens and you'll solve the problem. – user4581301 Mar 06 '20 at 22:49
  • 1
    I always worry when I see a loop with a `<=` in it. Check the range of `j` that results from `for ( int j = 0; j <= i; j++ )` to make certain it's what you expect. – user4581301 Mar 06 '20 at 22:51
  • 1
    the problem is `*(_2darray + i) = new int[i];` given that the for loop is initialized with i=0. You are allocating an array with zero items in it and then writing to it – jwezorek Mar 06 '20 at 23:00
  • `int** _2darray = new int* [size];` allocates for `size` **pointers**. `*(_2darray + i) = new int[i];` allocates for `i int` and assigns the starting address for that block to your pointers in turn. When you want to free the memory, you must first loop over your **pointers** freeing the allocated blocks of `int` before freeing the block of pointers. `for (int i = 0; i < size; i++) delete[] _2darray[i];` then free your block of pointers, `delete[] _2darray;`. (note: there are no "arrays" involved, you have allocated blocks of memory) Also note: `_2darray[i]` and `_2darray[i][j]` are readable. – David C. Rankin Mar 06 '20 at 23:00
  • Turns out the j <= i was really the problem, now it is running smoothly, thank you! – sigmund Mar 06 '20 at 23:03
  • Oh... yes, that will kill you every time... – David C. Rankin Mar 06 '20 at 23:04
  • EDIT: Also @jwezorek comment is true, i corrected it with: *(_2darray + i) = new int[i + 1]; – sigmund Mar 06 '20 at 23:24

2 Answers2

2

Your delete logic is correct.

The error message means that your program is writing to memory that is out of bounds. The comparison j <= i is not what is incorrect here however -- I mean assuming the program is currently generating the output you want.

Just note that you want your ith array to contain i+1 items. Specifically notice the zeroth array must contain one item (namely zero) so *(_2darray + i) = new int[i] should be *(_2darray + i) = new int[i+1].

With that change in place the for loops with the j <= i comparisons are correct. Index j is going to iterate over each item in the ith array which contains i+1 items. The comparison j < i will yield only i iterations when starting from zero so you do need j <= i in this case even though such a comparison is non-standard looking. Consider j < i+1, which is equivalent but might be clearer.

jwezorek
  • 3,125
  • 1
  • 19
  • 30
0
for ( int i = 0; i < size; i++ )
{
    *(_2darray + i) = new int[i];
     //...
}  

For first iteration, when i=0 you do:

*(_2darray + i) = new int[0];  

This is not a good way to allocate memory. see this C++ new int[0] — will it allocate memory?
And after you do:

for ( int j = 0; j <= i; j++ )

it should be:

for ( int j = 0; j < i; j++ )
Landstalker
  • 1,285
  • 5
  • 9