如何在C中分配和声明结构数组的3D?

dsb*_*dsb 7 c arrays struct typedef allocation

如何在C中分配和声明结构的3D数组?你首先分配数组还是声明它?我觉得你必须先分配它,这样你就可以声明它在堆上了,但那么你如何分配尚未制作的东西呢?另外,您应该一次性还是逐个元素地分配它?我也正确地将结构放入数组中?我对如何做的猜测是:

header.h

struct myStruct{
   int a;
   int b;
}; 
typedef struct myStruct myStruct_t;
Run Code Online (Sandbox Code Playgroud)

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;
}    
Run Code Online (Sandbox Code Playgroud)

jsc*_*410 1

有几种不同的方法可以做到这一点,具体取决于您的需求。首先,您可以在堆栈上分配数组(在 C99 和某些编译器中),如下所示:

myStruct_t arr[length][height][depth];
Run Code Online (Sandbox Code Playgroud)

如果您希望将其分配在堆上,那么您可以执行适当大小的单个分配。然后,您可以自己进行索引计算,也可以让指针为您完成这项工作(在 C99 和某些编译器中):

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 */
Run Code Online (Sandbox Code Playgroud)

或者您可以手动分配多个维度。

#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;
}
Run Code Online (Sandbox Code Playgroud)

最后一个版本为其包含的所有显式指针使用了更多的内存,其内存局部性更差,并且正确分配和回收要复杂得多。但是,它确实允许沿您的尺寸使用不同的尺寸。例如,数组的arr[0][4]大小可以与arr[0][7]您需要的大小不同。

如果您想在堆上分配它,那么您可能需要具有单个分配和多维指针(如果可用)的第二个版本,或者使用适当的数学手动进行索引。