繁体   English   中英

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

[英]How to allocate and declare a 3D of array of structs in C?

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

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;
}    

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

myStruct_t arr[length][height][depth];

如果您希望在堆上分配它,那么您可以执行适当大小的单个分配。 然后,您可以自己进行索引计算,也可以使指针为您完成工作(在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 */

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

#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;
}

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

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

简单的方法是:

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

然后你的循环可以访问arr2[x][y][z].a = rand(); 等等。 如果您不熟悉这种调用calloc请参阅此处 像往常一样使用malloc,在继续之前检查arr2NULL

三指针方法实际上并不是一个实用的解决方案。 如果编译器不支持可变修改类型,则应将数组展平为1-D。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM