I'm using the following C function to emulate a 4D array. Other than adding additional loops, is there a good way to make this function generic enough to create n-dimensional arrays?
double ****alloc_4D_data(int wlen, int xlen, int ylen, int zlen)
{
int i,j,k;
double ****ary = (jdouble****)malloc(wlen*sizeof(jdouble***));
for (i = 0; i < wlen; i++)
{
ary[i] = (jdouble***)malloc(xlen*sizeof(jdouble**));
for (j = 0; j < xlen; j++)
{
ary[i][j] = (jdouble**)malloc(ylen*sizeof(jdouble*));
for (k = 0; k < ylen; k++)
{
ary[i][j][k] = (jdouble*)malloc(zlen*sizeof(jdouble));
}
}
}
return ary;
}
-
2Why not malloc it at a single go?Uchia Itachi– Uchia Itachi2013年09月15日 16:46:08 +00:00Commented Sep 15, 2013 at 16:46
-
1It isn't trivial to add the extra dimensions other than by adding more loops. You will need to consider the memory release process too; also, the clean up if any of the allocations above fails.Jonathan Leffler– Jonathan Leffler2013年09月15日 16:46:59 +00:00Commented Sep 15, 2013 at 16:46
-
You can drop the castsEd Heal– Ed Heal2013年09月15日 16:51:20 +00:00Commented Sep 15, 2013 at 16:51
-
This specific function? No. A function (coupled with a multi-dim array function fmaily and a traits struct to hold the dimension info)? Yes.WhozCraig– WhozCraig2013年09月15日 17:06:35 +00:00Commented Sep 15, 2013 at 17:06
2 Answers 2
In C language, every elements of the multi dimensional array are stored in a continual memory area. So you just need to calculate the total number of elements of all N dimensional and malloc the whole memory. Such as:
/* int *Nlen is a N length array to store every dimensional array length
* int N is the Nlen array length indicates how many dimensions.
*/
double *alloc_ND_data(int wlen, int *Nlen, int N)
{
int i;
int total = 1;
double *array;
for(i = 0; i < N; i ++) {
/* Every dimension should mul the next depth dimension size */
total *= Nlen[i];
}
array = malloc(wlen*total*sizeof(jdouble));
return array;
}
2 Comments
The arrays you build in this way have very obvious recursive structure. I.e. i-th level memory is just an array of pointers to (i-1)-th level memory. Only the 0-th level memory contains the actual objects instead of pointers. So, you can easily implement it in that way, passing in the sizes in a separate integer array.
The recursion in this case is going to be tail recursion, meaning that it can be rather easily replaced with a genuinely cyclic implementation (with no need for intermediate LIFO storage). But to me it looks like one of those cases where recursion will work fine and will look more readable.