Home > Mobile >  Got a message free(): invalid pointer, when running C code
Got a message free(): invalid pointer, when running C code

Time:11-07

I wanted to allocate memory for a 2d double variable in C, and then free the memory, but got message: "free(): invalid pointer" when running the code.

Any idea where is the problem?

The code is listed below

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

double **allocate_2d_double(int rows_upper_lim, int cols_upper_lim){
//want to allocate arrays starting from 1 to rows_upper_lim, 1 to cols_upper_lim
#define rows_lower_lim 1
#define cols_lower_lim 1
  int i, no_of_rows=rows_upper_lim-rows_lower_lim 1,
    no_of_cols=cols_upper_lim-cols_lower_lim 1;
  double ** a;
  a=(double **) malloc(((no_of_rows 1)*sizeof(double*)));
  if(!a){
    printf("Memory allocation 1 failed in allocate_wts\n");
    exit(1);
  }
  a-=rows_lower_lim;
  /* Allocate rows and set pointers to them */
  a[rows_lower_lim]=(double *) malloc
    (((no_of_rows 1)*(no_of_cols 1))*sizeof(double));
  if(!a[rows_lower_lim]){
    printf("Memory allocation 2 failed in allocate_wts\n");
    exit(1);
  }
  a[rows_lower_lim] -=cols_lower_lim;
  for(i=rows_lower_lim 1; i<=rows_upper_lim; i  )
    a[i]=a[i-1] no_of_cols;
  /* Return pointer to array of pointers to row */
  return a;
}

void free_2d_double(double **a){
  if(a[1]) free (a[1]);
  if(a) free (a);
}

int main(void) {
  double **tt;
  int nn1=2, nn2=3;
  int i,j;
  tt=allocate_2d_double(nn1, nn2);
  for (i=1; i<=nn1; i  ){
    for (j=1; j<=nn2; j  ){
      tt[i][j]=i j;
      printf("tt[%d][%d]=%f\n",i,j,tt[i][j]);
    }
  }
  free_2d_double(tt);
  return 0;
}

CodePudding user response:

It is hard to understand what your code is doing (for sure not allocating 2D array). If you want to allocate 2D:

void *allocate_2d_double(size_t rows_upper_lim, size_t cols_upper_lim)
{
    double (*arr)[cols_upper_lim] = malloc(rows_upper_lim * sizeof(*arr));
    return arr;
}

void free_2d_double(void *a){
    free (a);
}

int main(void) {
  int nn1=2, nn2=3;
  double (*tt)[nn2];
  int i,j;
  tt=allocate_2d_double(nn1, nn2);
  for (i=1; i<=nn1; i  ){
    for (j=1; j<=nn2; j  ){
      tt[i - 1][j - 1]=i j;
      printf("tt[%d][%d]=%f\n",i-1,j-1,tt[i - 1][j - 1]);
    }
  }
  free_2d_double(tt);
  return 0;
}

or better:

int main(void) {
  int nn1=2, nn2=3;
  double (*tt)[nn2];
  int i,j;
  tt=allocate_2d_double(nn1, nn2);
  for (i=0; i<nn1; i  ){
    for (j=0; j<nn2; j  ){
      tt[i][j]=i j   2;
      printf("tt[%d][%d]=%f\n",i,j,tt[i][j]);
    }
  }
  free_2d_double(tt);
  return 0;
}

Remember that indexes in C start from 0 (zero)

CodePudding user response:

The function free requires the memory address that were returned by malloc to be passed to that function.

However, you are modifying the addresses returned by malloc in the following lines:

a-=rows_lower_lim;

and

a[rows_lower_lim] -=cols_lower_lim;

You should not pass these modified addresses to free, as that invokes undefined behavior. Instead, if you must modify these addresses, you may want to remember the original addresses in a separate variable, in order to later pass them to free.

  •  Tags:  
  • c
  • Related