Search code examples
arrayscpointersmultidimensional-arrayvariable-length-array

Implementing a 3D array as a pointer to a variable length array


I just learned about variable length arrays in C, and somebody suggested to me that I can realize a 3D array-like object in C simply as a pointer to a variable length array. A simple implementation would look as follows:

#include <stdio.h>
#include <stdlib.h>

int main( int argc, char *argv[] ) {

    size_t  ii, jj, kk,
            Nx, Ny, Nz;

    Nx  = 2;
    Ny  = 3;
    Nz  = 4;

    // initialize 3D array as pointer to a variable length array
    double (*arr3d)[Ny][Nz] = calloc(Nx, sizeof *arr3d);

    for( ii=0 ; ii<Nx ; ++ii )
        for( jj=0 ; jj<Ny ; ++jj )
            for( kk=0 ; kk<Nz ; ++kk )
                printf( "arr3d[%ld,%ld,%ld] = %f, address = %p\n",
                    ii, jj, kk, arr3d[ii][jj][kk], &arr3d[ii][jj][kk] );

    free(arr3d);
    return 0;

}

In my understanding, one advantage (besides of the one-line implementation) is that arr3d can be simply passed to a function,

int doSomething( size_t dim1, size_t dim2, size_t dim3, double arr3d[dim1][dim2][dim3] );

by calling this function in the main function as follows:

doSomething( Nx, Ny, Nz, arr3d );

My question now, is this a valid implementation of a 3D array-like object or will I run into some trouble ? Note that in the actual case, the dimensions are larger by roughly a factor of 1000 each.


Solution

  • If you have an array like

    double a[Nx][Ny][Nz];
    

    then you may write

    double (*arr3d)[Ny][Nz]  = a;
    

    that is the pointer arr3d points to the first element of the array a that has the type double{Nt][Nz].

    So this memory allocation

    double (*arr3d)[Ny][Nz] = calloc(Nx, sizeof *arr3d);
    

    is correct. There is in fact allocated dynamically a thre-dimensional array and the pointer arr3d points to the first element of the array.