Dynamic Allocation of Three-Dimensional Arrays in C

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

Leave a comment