Search code examples
cpointersheap-dump

C: Heap block at ### modified at ### past requested size of ###


So I'm storing a 2D dynamic Array into a matrix struct:

struct Matrix {
    int ncol;
    int nrow;
    double **mat;
};
typedef struct Matrix Matrix;

I then have a function that takes the contents from a 2D array and stores it into the matrix:

// Initializes matrix mat whose values are the passed in 2D array
// Made Matrix **mat a double pointer so that I can initialize the Matrix *pointer from Main
void matrix_initializeFromArray(Matrix **mat, int nrow, int ncol, double array[][ncol]) {
    (*mat) = (Matrix*) malloc(sizeof(Matrix*));
    (*mat)->mat = (double**) malloc(nrow*sizeof(double*));
    for(int i = 0; i < nrow; i++) {
        (*mat)->mat[i] = (double*) malloc(ncol*sizeof(double*));
        for(int j = 0; j < ncol; j++) { // intialize all values to array values
            (*mat)->mat[i][j] = array[i][j];
        }
    }
    (*mat)->ncol = ncol;
    (*mat)->nrow = nrow;
}

Where this is the destructor for the matrix:

// Destructor
void matrix_destructor(Matrix **mat) {
    for(int i = 0; i < (*mat)->nrow; i++) {
        free((*mat)->mat[i]);
    }
    free((*mat)->mat);
    free(*mat);
}

A small example of this is the following:

void main() {
Matrix *temp;
    double array[1][1];
    array[0][0] = 34;
    matrix_initializeFromArray(&temp, 1, 1, array);
    matrix_print(temp);
    matrix_destructor(&temp);
}

This code executes normally on gdb and valgrind in my Linux Ubuntu but for some reason it creates this error while I run it on Windows.

warning: HEAP[a.exe]:
warning: Heap block at 00B51710 modified at 00B5171C past requested size of 4

I ran through the gdb on Windows and it occurs at this line in the destructor on the first loop: free((*mat)->mat[i]);

Any Help?


Solution

  • I have simplified your code, matrix_print is missing The issue was with the malloc when you allocate something you get a pointer to the memory, for example malloc(sizeof(double)); returns a pointer to a memory area that can store a double so a double *

    malloc(sizeof(double*)); returns a pointer to a memory are that can store a pointer to a double, so a double **`

    #include <stdio.h>
    #include <stdlib.h>
    
    struct Matrix {
        int ncol;
        int nrow;
        double **mat;
    };
    typedef struct Matrix Matrix;
    
    void matrix_initializeFromArray(Matrix *mat, int nrow, int ncol, double array[][ncol]) {
        mat->ncol = ncol;
        mat->nrow = nrow;
        mat->mat = malloc(nrow * sizeof(double*));
        for(int i = 0; i < nrow; i++) {
            mat->mat[i] = malloc(ncol*sizeof(double));
            for(int j = 0; j < ncol; j++) { // intialize all values to array values
                mat->mat[i][j] = array[i][j];
            }
        }
    }
    
    void matrix_wipe(Matrix *mat) {
        for(int i = 0; i < mat->nrow; i++) {
            free(mat->mat[i]);
        }
        free(mat->mat);
    }
    
    int main(void) {
        Matrix temp;
        double array[1][1];
        array[0][0] = 34;
        matrix_initializeFromArray(&temp, 1, 1, array);
        matrix_wipe(&temp);
        return 0;
    }