# Thread: dynamically allocating 4D arrays

1. ## dynamically allocating 4D arrays

Hello

Does anybody have or no where I can find code for dynamic allocation of 4D arrays.

Thank you

2. Originally Posted by Marv
Hello

Does anybody have or no where I can find code for dynamic allocation of 4D arrays.

Thank you
Sigh... It's ugly in C, unfortunately.

Code:
```int ****array_4d;
int dim1 = 5;
int dim2 = 5;
int dim3 = 5;
int dim4 = 5;
int i, j, k;

array_4d = calloc(dim1, sizeof(array_4d[0]));
for(i = 0; i < dim1; i++)
{
array_4d[i] = calloc(dim2, sizeof(array_4d[0][0]));
for(j = 0; j < dim2; j++)
{
array_4d[i][j] = calloc(dim3, sizeof(array_4d[0][0][0]));
for(k = 0; k < dim3; k++)
{
array_4d[i][j][k] = calloc(dim4, sizeof(array_4d[0][0][0][0]));
}
}
}```
The version with appropriate error handling is even uglier. And freeing such a beast when you are finished with it also involves loops-in-loops-in-loops.

This can be made much more beautiful and general with some arcane pointer stuff, and recursive functions. Enough interested parties might convince me to post it.

3. Brewbuck

Thanks for the very speedy reply! I will give ypour code a try and make my own function to free
the memory. I was sort of hoping that someone could point me to a good web resource for such
things. Maybe even code for dynamic allocation of arbitrary dimensional arrays (and freeing routines).

Thanks a lot,

4. If your array is rectangular, you should just use a 1D array and treat it as an N-D array (where N == 4 in your case). For example, if the dimensions are n_0 x n_1 x n_2 x n_3, allocate a dynamic array a of length n_0 * n_1 * n_2 * n_3. Then array[i][j][k][l] corresponds to a[i*n_1*n_2*n_3 + j*n_2*n_3 + k*n_3 + l] = a[l + n_3*(k + n_2*(j + n_1*i))]. This makes allocating and deallocating trivial. It's also the only way to write code that sets the number of dimensions dynamically, since such code can't use explicit indexing for each dimension.

5. Brewbuck

Also "Numerical Recipes in C" (which does up to 3D dyn alloc) does not do so many calls to calloc. It
has three calls only (one for each dim).

6. Thanks robatino

That was my first inclination but as I write code for my particular project I am finding that indexing into a
1D array to mimick a 4D array just gets difficult to read (and debug).

7. Well, I guess you could write functions (or even macros) to access the array.

You could have something like:
Code:
```int* p;
p = create_4d(a, b, c, d);
int n = get_4d(p, e, f, g, h);
set_4d(p, 100,  e, f, g, h);```

8. Originally Posted by Marv
Brewbuck

Also "Numerical Recipes in C" (which does up to 3D dyn alloc) does not do so many calls to calloc. It
has three calls only (one for each dim).
But you said 4 dimensions?

9. Originally Posted by Marv
Brewbuck

Also "Numerical Recipes in C" (which does up to 3D dyn alloc) does not do so many calls to calloc. It
has three calls only (one for each dim).
Three is smaller than four. That means, if you're allocating a four dimensional array, you have one more allocation than you would for three.

Quzah.

10. Does anybody know which would be faster:

(1) indexing into a 1D array with the macro suggested by anon or
(2) indexing into a 4D array using usual array syntax.

Thanks again

(2) indexing into a dynamically allocated 4D array (created using brewbeck's method or some 4D version of the NumRec in C code) using usual array syntax.

12. Use what you understand. The performance of both options should be about the same. If you declared a 4d array with automatic memory the compiler accesses the array the same way it is in 1 except with less macros maybe. Meanwhile the other option just hides the math, but adds a lot of code for the same performance. Obviously, performance is not the issue here.

13. Thanks citizen

14. FWIW, there was a thread on this topic a while back -- although the requirement was for a dynamically allocated contiguous 4D array -- here is Salem's post.

15. Dave_sinkula

Thanks. I guess could just start with that code and edit it. I was really hoping for something well tested but i can't be
too picky.