如何在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;
}
答案 0 :(得分:1)
根据您的需要,有几种不同的方法可以做到这一点。首先,您可以在堆栈上分配您的数组(在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]
不同。
如果要在堆上分配它,那么您可能希望第二个版本具有单个分配和多维指针(如果可用),或者使用适当的数学手动自己编制索引。
答案 1 :(得分:1)
简单的方法是:
myStruct_t (*arr2)[height][width] = calloc( length * sizeof *arr );
然后您的循环可以访问arr2[x][y][z].a = rand();
,依此类推。如果您不熟悉这种调用calloc
,see here的方式。像往常一样使用malloc,在继续之前检查arr2
对NULL
。
三指针方法实际上并不是一个实用的解决方案。如果编译器不支持可变修改类型,则应将数组展平为1-D。