Search code examples
c++dynamic-arraysdynamic-memory-allocation

Why does this fix a heap corruption?


So I've got code:

    float **array = new float*[width + 1]; //old line was '= new float*[width]'

    //Create dynamic 2D array
    for (int i = 0; i < width; ++i) {
        array[i] = new float[height + 1]; //old line was '= new float[height]'
    }

    //Hardcode 2D array for testing
    for (int i = 0; i < height; ++i) {
        for (int j = 0; j < width; ++j) {
            array[i][j] = i + j;
         }
     }

    //deallocate heap memory
    for (int i = 0; i < width; ++i) {
        delete [] array[i]; //Where corrupted memory error used to be
    }
    delete [] array;

(For the record, I know it would be more efficient to allocate a single block of memory, but I work closely with scientists who would never understand why/how to use it. Since it's run on servers, the bosses say this is preferred.)

My question is why does the height+1/width+1 fix the corrupted memory issue? I know the extra space is for the null terminator, but why is it necessary? And why did it work when height and width were the same, but break when they were different?

SOLN: I had my height/width backwards while filling my array... -.-; Thank you to NPE.


Solution

  • The following comment is a red herring:

       delete [] array[i]; //Where corrupted memory error used to be
    

    This isn't where the memory error occurred. This is where it got detected (by the C++ runtime). Note that the runtime isn't obliged to detect this sort of errors, so in a way it's doing you a favour. :-)

    You have a buffer overrun (probably an off-by-one error in a loop) in the part of your code that you're not showing.

    If you can't find it by examining the code, try Valgrind or -fsanitize=address in GCC.

    edit: The issue with the code that you've added to the question:

    //Hardcode 2D array for testing
    for (int i = 0; i < height; ++i) {
        for (int j = 0; j < width; ++j) {
            array[i][j] = i + j;
         }
     }
    

    is that it has width and height (or, equivalently, i and j) the wrong way round. Unless width == height, your code has undefined behaviour.