datapanda
datapanda

Reputation: 517

Out of scope declaration of a multidimensional array

This question is in reference to the solution/explanation provided here Allocating variable length multi dimensional arrays ( see the accepted answer).

In my case I am using the same function for defining a 3D array like following

void arr_alloc (int x, int y, int z, int(**aptr)[x][y][z])
{
  *aptr = malloc( sizeof(int[x][y][z]) ); // allocate a true 3D array
  assert(*aptr != NULL);
} 

For the codebase I am working on, which is a huge project repository, earlier I was using pointers to pointers to pointers to type (***array) and then interleaving such that I can use it as a 3D (pseudo)array. For this I used to declare the variable as extern int ***array and define the pointer in a separate header file as int ***array. My question - (a) For the new function in place what should be the declaration and definition for the array given that the SO reference answer uses the declaration and definition such as

int x = 2;
int y = 3;
int (*aptr)[x][y];

(b) Incentive of using size_t vs int as the indexing variable given that size_t occupies 8 bytes whereas int occupies 4 bytes.

PS. I checked in gdb the variable type after the declaration and definition line mentioned above (also in the SO answer) which is (int (*)[variable length][variable length][variable length]) 0x0

Edit : Please note that this question is about the declaration and definition of the array / array pointer and not the declaration of the function that allocates and sets up the array in place.

Upvotes: 2

Views: 250

Answers (1)

dbush
dbush

Reputation: 224417

The function declaration is correct for allocating a 3D array. A pointer to such an array would have type int (*)[a][b][c], so the function needs to accept the address of a pointer of that type to write to it, i.e. int (**)[a][b][c], which is what you have.

To use this function you would need to call it as follows:

int s1=2, s2=3, s3=4;
int (*p)[s1][s2][s3];
arr_alloc(s1,s2,s3,&p);

Then you could write to the 3D array like this:

int i,j,k;
int n = 0;
int i,j,k;
int n = 0;
for (i=0;i<s1;i++) {
    for (j=0;j<s2;j++) {
        for (k=0;k<s3;k++) {
            (*p)[i][j][k] = n++;
        }
    }
}

EDIT:

A true multidimensional array must declare a size for all dimensions except for the first. If your array is declared at file scope, that means the size of those dimensions must be compile time constants.

If the dimensions have to vary, you'll need to make it a void * and cast as necessary. You loose some type checking here, but it's the only way to do this:

int s1, s2, s3;
void *arr;

void arr_alloc (int x, int y, int z)
{
  int (*p)[x][y][z] = malloc( sizeof(int[x][y][z]) );
  assert(p != NULL);
  arr = p;
  s1=x;
  s2=y;
  s3=z;
}

int main()
{
    arr_alloc(2,3,4);
    int (*p)[s1][s2][s3] = (int(*)[s1][s2][s3])arr;

    int i,j,k;
    int n = 0;
    for (i=0;i<s1;i++) {
        for (j=0;j<s2;j++) {
            for (k=0;k<s3;k++) {
                    (*p)[i][j][k] = n++;
            }
        }
    }
    for (i=0;i<s1;i++) {
        for (j=0;j<s2;j++) {
            for (k=0;k<s3;k++) {
                    printf("%d:%d:%d=%d\n",i,j,k,(*p)[i][j][k]);
            }
        }
    }
    free(p);
    return 0;
}

Upvotes: 2

Related Questions