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