How to highlight and declare a 3D array of structures in C?

How do you select and declare a 3D array of structures in C? Did you first allocate an array or declare it? I feel that you need to allocate it first so that you can declare it so that it is on the heap, but then how do you allocate what has not yet been done? Also, should you select everything at once or element by element? Also, do I correctly place structures in an array? My hunch about how to do this would be:

header.h

struct myStruct{ int a; int b; }; typedef struct myStruct myStruct_t; 

main.c

 #include "header.h" #include <stdio.h> #include <stdlib.h> int main(void){ int length=2; int height=3; int width =4; myStruct_t *elements; struct myStruct arr = (*myStruct_t) calloc(length*height*width, sizeof(myStruct); //zero based array arr[length-1][height-1][width-1]; int x=0; while(x<length){ int y=0; while(y<height){ int z=0; while(z<depth){ arr[x][y][z].a=rand(); arr[x][y][z].b=rand(); z++; } y++; } x++; } return 0; } 
+7
c arrays struct typedef allocation
source share
2 answers

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.

+1
source share

A simple way is:

  myStruct_t (*arr2)[height][width] = calloc( length * sizeof *arr ); 

Then your loop can access arr2[x][y][z].a = rand(); and so on. If you are not familiar with this method of calling calloc , see here . As usual with malloc, before proceeding, check arr2 for NULL .

The triple pointer approach is not really a practical solution. If your compiler does not support modified types, then the array should be flattened to 1-D.

+1
source share

All Articles