Reputation: 517
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
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