There are several ways to do this, depending on what you want. First, you can allocate your array on the stack (in C99 and some compilers) as follows:
myStruct_t arr[length][height][depth];
If you want it to be allocated in a heap, you can make one selection of the appropriate size. You can either independently calculate the index, or make a pointer to work for you (in C99 and some compilers):
void *buf = malloc(length * height * width * sizeof(myStruct_t)); myStruct_t *arr = buf; myStruct_t (*arr2)[height][width] = buf; /* TODO: check return of malloc */ ... arr[x * height * width + y * width + z].a = rand(); /* indexing the C89 way */ arr2[x][y][z].b = rand(); /* indexing the C99 way */
Or you can manually select multiple dimensions.
#include <stddef.h> #include <stdlib.h> typedef struct myStruct { int a, b; } myStruct_t; int main() { myStruct_t ***arr; int length = 5000, height = 1000, depth = 20; int x, y, z; int ret = 1; if (NULL == (arr = malloc(length * sizeof(myStruct_t**)))) goto FAIL; for (x = 0; x < length; ++x) { if (NULL == (arr[x] = malloc(height * sizeof(myStruct_t*)))) goto FAIL_X; for (y = 0; y < height; ++y) { if (NULL == (arr[x][y] = malloc(depth * sizeof(myStruct_t)))) goto FAIL_Y; for (z = 0; z < depth; ++z) { arr[x][y][z].a = rand(); arr[x][y][z].b = rand(); } } } /* TODO: rest of program logic */ /* program successfully completed */ ret = 0; /* reclaim arr */ FAIL_CLEANUP: /* label used by TODO code that fails */ for (x = length - 1; x >= 0; --x) { for (y = height - 1; y >= 0; --y) { free(arr[x][y]); FAIL_Y: ; } free(arr[x]); FAIL_X: ; } free(arr); FAIL: return ret; }
This latest version uses a lot more memory for all the explicit pointers that it contains, its memory locality is worse and much more difficult to correctly allocate and restore. However, it allows different sizes according to your sizes. For example, the arr[0][4] array may have a different size than arr[0][7] if you need it.
If you want to allocate it on the heap, then you probably want the second version to have one purpose and a multidimensional pointer (if available) or to perform manual indexing yourself using the appropriate math.
jschultz410
source share