Search code examples
cpointersmallocfreerealloc

Why do I get an error of "free(): invalid pointer"?


I am fairly new to C and I am using gcc compiler with -ansi.

I am trying to implement Strassen's algorithm for square matrix multiplication in C. As a warmup, I am just implementing a recursive algorithm first, which breaks each matrix into 4 submatrices (with the idea that I'll implement Strassen's algorithm later).

The program is as follows:

#include <stdio.h>
#include <stdlib.h>
int** read_square_matrix(int size); /*returns dynamically allocated size x size matrix*/
int** square_matrix_multiply_helper(int** A,int** B, int row1, int col1, int row2, int col2, int size); /*recursively compute product. Assumes size is power of two*/
int** square_matrix_multiply(int** A,int** B, int size);/*expands dimension to a power of two if necessary and computes product*/
int main()
{
    int** A;
    int** B;
    int** C;
    int i,size;

    printf("Enter size: ");
    scanf("%d",&size);

    printf("Enter array A: ");
    A = read_square_matrix(size);

    printf("Enter array B: ");
    B = read_square_matrix(size);

    C = square_matrix_multiply(A,B,size);
    printf("Their product is:\n");
    print_square_matrix(C,size);
    for (i=0;i<size;++i)
    {
        free(A[i]);
        free(B[i]);
        free(C[i]);
    }
    free(A);
    free(B);
    free(C);

    return 0;
}

The code works fine for size=1,2,4. When I try two 3x3 matrices, say all 1, is where it fails. Specifically free(A[i]) fails on the first iteration with the error

free(): invalid pointer

Now by looking around, seems like this means that A[i] was not allocated by malloc. I don't see how this is possible. Here is the code for the matrix multiplication:

int** square_matrix_multiply(int** A, int** B, int size)
{
    int** C;
    int power,i,j;
    power = 1;
    while (power<size)
        power*=2;
    if (size<power)
    {
        A = realloc(A,power*sizeof(int*));
        B = realloc(B,power*sizeof(int*));
        for (i=0;i<size;++i)
        {
            A[i] = realloc(A[i],power*sizeof(int));
            B[i] = realloc(B[i],power*sizeof(int));
            for (j=size;j<power;++j)
            {
                A[i][j] = 0;
                B[i][j] = 0;
            }
        }
        for (i=size;i<power;++i)
        {
            A[i] = malloc(power*sizeof(int));
            B[i] = malloc(power*sizeof(int));
            for (j=0;j<power;++j)
            {
                A[i][j] = 0;
                B[i][j] = 0;
            }
        }
    }
    C = square_matrix_multiply_helper(A,B,0,0,0,0,power);
    for (i=size;i<power;++i)
    {
        free(A[i]);
        free(B[i]);
        free(C[i]);
    }
    A = realloc(A,size*sizeof(int*));
    B = realloc(B,size*sizeof(int*));
    C = realloc(C,size*sizeof(int*));
    for (i=0;i<size;++i)
    {
        A[i] = realloc(A[i],size*sizeof(int));
        B[i] = realloc(B[i],size*sizeof(int));
        C[i] = realloc(C[i],size*sizeof(int));
    }
    return C;
}

I've been looking at this for hours, and I cannot figure out what's wrong. Can someone help me please? Thank you! EDIT: implementation of read_square_matrix:

int** read_square_matrix(int size)
{
    int** C;
    int i,j;
    C = malloc(size*sizeof(int*));
    for (i=0;i<size;++i)
    {
        C[i] = malloc(size*sizeof(int));
        for (j=0;j<size;++j)
            scanf("%d",&C[i][j]);
    }
    return C;
}

Solution

  • In the square_matrix_multiply function, you should pass the addresses of int** A & int** B.Change it to int** square_matrix_multiply(int*** A, int*** B, int size), the C = square_matrix_multiply(A,B,size) should be C = square_matrix_multiply(&A,&B,size), and change the implements of square_matrix_multiply.