0

I get a 'double free or corruption' error while freeing up an 3d array. Can anyone please tell me where is the problem in the code? The size of the array is 2*N*N. Value of N here is 100. Even without casting, same result. Here is the code:

// Mallocing 
double ***h = malloc(2 * (sizeof(double**)));
for(i = 0; i < N; i++) {
    h[i] = malloc(N * sizeof(double*));
    for(j = 0; j < N; j++) {
        h[i][j] = malloc(N * sizeof(double));
    }
}

// Freeing
for(i = 0; i < N; i++) {
    for(j = 0; j < N; j++) {
        free(h[i][j]);
    }
    free(h[i]);
}
free(h);

The program works fine but at the end I get an error 'double free or corruption (!prev): 0x08cd24f8' Aborted (core dumped).

Sohi
  • 114
  • 1
  • 9

5 Answers5

2

For the first dimension, you allocate 2 elements:

double ***h = (double***) malloc(2 * (sizeof(double**)));

But you treat it as if it had N elements:

for(i = 0; i < N; i++) {
    h[i] = ...

Change outermost loop comparison on allocation and free to:

for(i = 0; i < 2; i++) {

Also don't cast return value of malloc. Also, your code is missing error handling, and will break if allocation fails.

user694733
  • 15,208
  • 2
  • 42
  • 68
1

As fas as I can see you allocate 2 items, then fill N of them.

double ***h = (double***) malloc(2 * (sizeof(double**)));
for(i = 0; i < N; i++) {
    h[i] = (double**) malloc(N * sizeof(double*));
    ....
    ....
}

You're overwriting not allocated space if N>2...

CiaPan
  • 9,381
  • 2
  • 21
  • 35
0

The problem's here:

double ***h = (double***) malloc(2 * (sizeof(double**)));
for(i = 0; i < N; i++) {
    // ...
}

You only malloc 2 elements, and iterate over N. I guess you wanted to have array of size N*N*N, but you ended up with 2*N*N instead.

So this:

double ***h = (double***) malloc(2 * (sizeof(double**)));

Should be:

double ***h = (double***) malloc(N * (sizeof(double**)));
rubikonx9
  • 1,403
  • 15
  • 27
0

If the value of N = 100 as in your comment then you need to allocate memory to hold N pointer-to-pointer where you have just 2 .

double ***h =  malloc(N * (sizeof(double*)));

Don't cast malloc()

Gopi
  • 19,784
  • 4
  • 24
  • 36
0

As others have pointed out, the specific problem causing the bug is you treating the dimension with 2 elements as if it had N elements.

The core reason for this however, is obfuscation. There are some rules I would strongly recommend you to follow:

  • Always allocate multi-dimensional arrays as true arrays allocated in adjacent memory. Reference.

  • Never allocate multi-dimensional arrays as pointer-to-pointer based lookup-tables that are fragmented all over the heap. Not only are they slower and make the code harder to read, they aren't actually arrays. You can't use them together with memcpy() etc.

    Unfortunately there are countless of bad C programming teachers and bad books that preach fragmented pointer-to-pointer lookup-tables. So many programmers have to unlearn this, it is frightening...

  • Never use more than two levels of indirection in your program. There should never be a reason to do so, all it does is to turn your program less readable (Reference MISRA-C:2012 rule 18.5). This is actually known as "three star programming" and it's not a flattering term.

  • Never cast the result of malloc, because it is pointless to do so.

What you should do:

double (*array)[Y][Z] = malloc( sizeof(double[X][Y][Z]) );
...
free(array);

Example:

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

#define X 2
#define Y 3
#define Z 4

int main (void)
{
  double (*array)[Y][Z] = malloc( sizeof(double[X][Y][Z]) );

  double count = 0.0;
  for(int x=0; x<X; x++)
  {
    for(int y=0; y<Y; y++)
    {
      for(int z=0; z<Z; z++)
      {
        array[x][y][z] = count++;
        printf("%f ", array[x][y][z]);
      }
      printf("\n");
    }
    printf("\n");
  }

  free(array);

  return 0;
}

To compile this, you need a compiler which is not older than 16 years.

Community
  • 1
  • 1
Lundin
  • 195,001
  • 40
  • 254
  • 396
  • Thank you very much for the valuable input. You provided really good points in there. Cheers – Sohi Feb 05 '15 at 06:03