Way back in time I ended up writing a C-function to dynamically allocate three-dimensional arrays. I still remember the struggle to get it right, and I realize that this is an amazing way to learning pointers. I have scanned through my old hard drives to get hold of it, but I am pretty sure it is lost forever.
What it achieved was to dynamically allocate memory equivalently to the static allocation (example size):
/* Statically allocate 256M doubles */ const int x = 1024, y = 1024, z = 256; double v[x][y][z];
In other words, it was creating a pointer ***v and then by calling malloc() several times it set a side memory according to the sizes of the constants x, y and z.
This is a powerful way of allocating memory on a if needed basis, and still keeping available the standard array notation ([][][]) — also enabling the programmer to free up that memory whenever he wants.
I decided to ask software engineer Viktor Kolesnikov in the team if he had ever done something like this. His response was not surprisingly: “Yes, no problem.”, and five minutes later I got a code snippet on Lync almost identical to how I remember my old code.
Viktor is from Russia, but currently lives in Norway. This man deserves some serious bragging because he is just a damn smart and extremely talented embedded developer. Thanks for the snippet, Viktor — I have modified it a bit and added the free function.
Now, let’s share it with the world!
#include <stdlib.h>
#include <stdio.h>
double ***dalloc_3d(double ***v, const int x, const int y, const int z);
void dfree_3d(double ***v, const int x, const int y);
int main(void)
{
double ***v = (double ***) NULL;
const int x = 1024, y = 1024, z = 256;
/* Dynamically allocate 256M doubles */
v = dalloc_3d(v, x, y, z);
/* Write/Read test */
v[14][32][3] = 1.0;
printf("%f\n", v[14][32][3]);
/* Free */
dfree_3d(v, x, y);
}
/* Dynamically allocate a three-dimensional array according to the sizes of
x, y and z. */
double ***dalloc_3d(double ***v, const int x, const int y, const int z)
{
v = (double***) malloc(sizeof(double**) * x);
for (int i = 0; i < x; i++ )
{
v[i] = ( double** ) malloc(sizeof(double*) * y);
for ( int j = 0; j < y; j++ )
{
v[i][j] = ( double* ) malloc( sizeof(double) * z);
/* Initialize all elements to zero */
for (int k = 0; k < z; k++)
{
v[i][j][k] = 0;
}
}
}
return v;
}
/* Dynamically free the three-dimensional array v given by the sizes of
x and y. */
void dfree_3d(double ***v, const int x, const int y)
{
for (int i = 0; i < x; i++ )
{
for ( int j = 0; j < y; j++ )
{
free(v[i][j]);
}
free(v[i]);
}
free(v);
}
