0
votes

I am trying to free a three dimensional pointer array representing a bmp image and whle it compiles ok I get SIGTRAP signals in gdb when debugging. My error message is

warning: HEAP[bmpsample.exe]:
warning: Heap block at 0061FFB8 modified at 0061FFCC past requested size of c.
Program received signal SIGTRAP, Trace/ breakpoint trap. 0x7787704e5 in ntdll!TpWaitForAlpcCompletion()
from ntdll.dll

The error occurs when I free the array after loading in the values from the bmp file. My code is as follows.

Allocation:

int ***alloc3D(int xlen, int ylen, int zlen) {
int i, j, ***array;
if ((array = malloc(xlen*sizeof(int**)))==NULL) {
    perror("Error in first assignment of 3D malloc\n");
}
// Allocate pointers for each row
for (i = 0; i < xlen; i++) {
    if ((array[i] = malloc(ylen*sizeof(int*)))==NULL){
        perror("Error in second assignment of 3D malloc\n");
    }
    // Allocate pointer for each column in the row
    for (j=0; j < ylen; j++) {
        if((array[i][j] = malloc(zlen*sizeof(int)))==NULL) {
            perror("Error in third assignment of 3D malloc\n");
        }
    }
}

Filling the array

int ***readBitmap(FILE *inFile, BmpImageInfo info, int*** array) {
    // Pixels consist of unsigned char values red, green and blue
Rgb *pixel = malloc( sizeof(Rgb) );
int read, j, i;
for( j=0; j<info.height; j++ ) {
    read = 0;
    for( i=0; i<info.width; i++ ) {
        if( fread(&pixel, 1, sizeof(Rgb), inFile) != sizeof(Rgb) ) {
                printf( "Error reading pixel!\n" );
        }
        array[j][i][1] = (int)(pixel->red);
        array[j][i][2] = (int)(pixel->green);
        array[j][i][3] = (int)(pixel->blue);
        read += sizeof(Rgb);
    }

    if ( read % 4 != 0 ) {
        read = 4 - (read%4);
        printf( "Padding: %d bytes\n", read );
        fread( pixel, read, 1, inFile );
    }
}
free(pixel);

return array;

}

Deallocation

void dealloc3D(int*** arr3D,int l,int m)
{
    int i,j;

    for(i=0;i<l;i++)
    {
        for(j=0;j<m;j++)
        {
                free(arr3D[i][j]);
        }
        free(arr3D[i]);
    }
    free(arr3D);
}

I suscpect that the problem lies in casting the RGB values from unsigned char to int, but I see no other way of doing it. If I simply assign integer values to the alloced array there is no problem with freeing them.

1
Did you learn to correctly use gdb? Did you ask for the backtrace (using the bt command of gdb) when the SIGTRAP occur? Did you compile your code with gcc -Wall -g ?Basile Starynkevitch
You are corrupting memory. Change fread(&pixel, 1, sizeof(Rgb), inFile) to fread(pixel, 1, sizeof(*pixel), inFile) and read += sizeof(Rgb); to read += sizeof(*pixel);. That way when and/or if the type of pixel changes there will be fewer things to change in your code.JimR
@BasileStarynkevitch I am compiling with both -Wall and -g without errors and bt full shows me that dealloc3D is called with the correct address to the array and the correct height and width. I am however very new to GDB and I only know the most basic controls.Simon Thordal
@JimR Thank you for the advice, changing &pixel to pixel did not help sadly. I should also mention that images are read correctly to the array (checked with Matlab).Simon Thordal
I am such an idiot. I am starting my indices from 1 when assigning the color values. The only reason my program gives a readable output is because I am doing the exactly same thing in a later function that converts the image to grayscale, which led me to believe that error had to be found in the deallocation. Sorry for wasting your time.Simon Thordal

1 Answers

2
votes

You have a problem with the first fread statement

fread(&pixel, 1, sizeof(Rgb), inFile)

which is reading into the pointer pixel, not into what pixel is pointing to. After that, any use of pixel is likely to corrupt the heap (or something else).