double free or corruption 3d array in C

蓝咒 提交于 2019-11-29 17:26:02

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.

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...

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**)));

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()

Lundin

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!