0

I try to init a matrix using dynamic memory allocation, for which I made a helper function. The problem appears when I try to free the memory. I'm getting double free or corruption error.

I understand what a double free error is, but can't spot it in my code.

void
delete_matrix(matrix_t *mat)
{
    for(int i = 0; i < mat->rows; i++)
    {
        free(mat->data[i]); /* It crashes at first iteration */
        mat->data[i] = NULL;
    }
    free(mat->data);
    mat->data = NULL;
}


int
init_matrix(matrix_t *mat, int rows, int cols)
{
    mat->rows = rows;
    mat->cols = cols;

    mat->data = (int**)malloc(rows * sizeof(int));

    for(int i = 0; i < rows; i++)
    {
        mat->data[i] = (int*)malloc(cols * sizeof(int));
    }
    return 0;
}

Full code on gdbonline.com:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

typedef struct
{
    int ** data;
    int rows;
    int cols;
}matrix_t;

int  init_matrix(matrix_t *mat, int rows, int cols);
void delete_matrix(matrix_t *mat);

int
main()
{
    printf("> Program started\n");

    matrix_t mat_A;
    init_matrix(&mat_A, 1000, 1000);
    delete_matrix(&mat_A);
    printf("> Program done\n");
    sleep(0);
    return 0;
}


int
init_matrix(matrix_t *mat, int rows, int cols)
{
    mat->rows = rows;
    mat->cols = cols;

    mat->data = (int**)malloc(rows * sizeof(int));
    if(!mat->data)
    {
        printf("! malloc error (init_matrix 1)\n");
        return -1;
    }

    for(int i = 0; i < rows; i++)
    {
        mat->data[i] = (int*)malloc(cols * sizeof(int));
        if(!mat->data[i])
        {
            printf("! malloc error (init_matrix 2)\n");
            return -1;
        }
    }
    return 0;
}


void
delete_matrix(matrix_t *mat)
{
    for(int i = 0; i < mat->rows; i++)
    {
        free(mat->data[i]);
        mat->data[i] = NULL;
    }
    free(mat->data);
    mat->data = NULL;
}

Thank you in advance.

KamilCuk
  • 120,984
  • 8
  • 59
  • 111
P47 R1ck
  • 148
  • 1
  • 12
  • 3
    `rows * sizeof(int)`? I guess you really wanted `rows * sizeof(int*)`. Or better yet `rows * sizeof *mat->data` If `sizeof(int) < sizeof(int*)`is true (which it generally is on a 64-bit system) then you would allocate to little memory and go out of bounds and have *undefined behavior* (and such errors like you get). – Some programmer dude Jul 05 '21 at 15:52
  • 1
    By the way, in C you [shouldn't really cast the result of `malloc`](https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) (or other functions returning `void*`). – Some programmer dude Jul 05 '21 at 15:55
  • Yes, the problem seems to be in the allocation. – P47 R1ck Jul 05 '21 at 16:07

1 Answers1

1

I'm getting double free or corruption error.

Corruption possible due to incorrect allocation.

//                                         v-v---- wrong type. 
// mat->data = (int**)malloc(rows * sizeof(int));
mat->data = malloc(sizeof *(mat->data) * rows);
//                 ^-----------------^ The right size by construction
//                                     No need to code the matching type 
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256