Search code examples
arrayscpointersmallocfree

Problems when freeing a dynamically allocated 2d array in C


I am desperately trying to free a 2d int array and can't manage to do so. I guess there's something wrong when i intialize the array? Could you please help me out?

    int rows = 2;
    int cols = 3;
    int *mfields = (int *) malloc(sizeof(int) * rows * cols);
    int **matrix = (int **) malloc(sizeof(int *) * rows);
    for (int i = 0; i < rows; i++) {
        matrix[i] = mfields + i * cols;
        for(int j=0; j<rows;j++) {
            matrix[i][j] = (i+1)*(j+1);
        }
    }
    for (int i = 0; i < rows; i++) {
        free((matrix[i]));
    }
    free(matrix);

Thanks in advance, Christian


Solution

  • Two chunks of memory are allocated:

    int *mfields = (int *) malloc(sizeof(int) * rows * cols);
    int **matrix = (int **) malloc(sizeof(int *) * rows);
    

    and therefore two chunks of memory should be freed:

    free(matrix);
    free(mfields);
    

    Freeing multiple chunks of memory, as this loop does:

        for (int i = 0; i < rows; i++) {
            free((matrix[i]));
    

    is incorrect, as it passes addresses to free that were never returned from malloc.

    Generally, it is not good to implement matrices as pointers-to-pointers. This prevents the processor from doing load prediction and impairs performance. If the C implementation(s) that will be used with the code support variable length arrays, then it is preferable to simply allocate one chunk of memory:

    int (*matrix)[cols] = malloc(rows * sizeof *matrix);
    

    If variable length array support is not available, then a program should allocate one chunk of memory and use manual calculations to address array elements. While this is may be more work for the programmer, it is better for performance:

    int *matrix = malloc(rows * cols * sizeof *matrix);
    for (int i = 0; i < rows; i++)
        for (int j = 0; j < cols; j++)
            matrix[i*cols + j] = (i+1) * (j+1);