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.