我试图创建一个初始化为零的整数的3D数组,每个固定大小表示为" dim"。
例如,对于dim = 3,它将有27个单元用于整数。
我试过了:
int ***board;
int **rows;
int *tried;
board = calloc(dim,sizeof(int**));
rows = calloc(dim*dim, sizeof(int*));
tried = calloc(dim*dim*dim, sizeof(int));
int i;
int j;
int k;
for (i=0 ; i<dim ; i++) {
board[i] = rows + i*dim*dim;
for (j=0 ; j<dim ; j++) {
board[i][j] = tried + j*dim + i*dim*dim;
}
}
for (i=0 ; i<dim ; i++) {
for (j=0 ; j<dim ; j++) {
for (k=0 ; k<dim ; k++) {
board[i][j][k] = 0;
}
}
}
尝试调试它,我发现它可以工作,直到:
board[1][1][0] = 0
然后程序卡住了,我无法找到原因。
有人可以解释一下吗?
谢谢!
答案 0 :(得分:4)
首先是关于代码中的错误。比较一下:
rows = calloc(dim*dim, sizeof(int*));
到此:
for (i=0 ; i<dim ; i++) {
board[i] = rows + i*dim*dim;
分配给rows
的数组的整个大小为dim*dim
个元素。因此,已经在此循环的第二次迭代中,您可以访问它越界。你可能意味着:
for (i=0 ; i<dim ; i++) {
board[i] = rows + i*dim;
正如我在评论中已经提到的,这是不 3D阵列。它通过使用指针来模仿代码中的用法,并且您在这里使用了一种聪明的技巧,因此您总共只需要3次分配。在以下条件下这可能是一个好主意:
dim
在运行时是可变的,因此您无法事先知道,如果其中一个条件不成立,使用真正的3D阵列要好得多。如果在离开您的功能后阵列不必存在并且尺寸不是巨大,那么只需使用具有自动存储持续时间的简单变量,例如
int board[3][3][3] = { 0 }; // possibly #define the dimension
或者,对于变量dim
,需要支持VLAs的编译器
int board[dim][dim][dim] = { 0 };
另一方面,如果数组很大并且/或者你需要从函数返回它,你确实必须动态分配它。然后使用以下内容:
int (*board)[3][3] = calloc(3, sizeof *board); // static size
int (*board)[dim][dim] = calloc(dim, sizeof *board); // dynamic case, with VLA suppport
另请注意,calloc()
已将已分配的内存设置为0
,因此无需遍历整个内存。
附注:
sizeof
,更喜欢表达形式,所以不要写
int *a = calloc(5, sizeof(int));
更好写
int *a = calloc(5, sizeof *a);
这可以避免以后更改a
的类型时的错误。
始终检查malloc()
和朋友的返回值 - 他们可能会返回空指针(例如,当您的内存不足时)。
1) VLA不存在于最早的标准C89 / C90中 - 它们作为强制性特征在C99中引入,但后来在C11中被选择。这允许C11编译器省略它们,这在例如时可能是有意义的。针对嵌入式系统。实际上,如果不是特殊目的,您可以安全地假设符合C11的编译器支持它们。
答案 1 :(得分:0)
我重写了你的代码,以显示3D数组的分配情况。正如评论中指出的那样,由于calloc为你做了这个,所以不需要将数组初始化为0。如果你使用malloc,数组就不会被初始化。
_GScene(QGraphicsScene)
你想要存储的内容取决于你,在我的例子中,我写了每个索引的计数器总和。
答案 2 :(得分:0)
以下代码为Unlicense。
我会建议一些不同的东西。只需创建一维数组并设置一些边界即可将其解释为3D。我为您添加了一些测试用例,以便更好地了解它的工作原理。别忘了看看calloc&#39;打电话是。这是代码:
#include <stdlib.h>
#include <stdio.h>
int getindex(int dim, int x, int y, int z) {
return z * dim * dim + y * dim + x;
}
void printarray(int* tdarray, int dim) {
printf("[\n");
for (int i = 0; i < dim; i++) {
printf("\t[\n");
for (int j = 0; j < dim; j++) {
printf("\t\t[");
for (int k = 0; k < dim; k++) {
if (k == 0) printf("%d", *(tdarray + getindex(dim, k, j, i)));
else printf(",\t %d", *(tdarray + getindex(dim, k, j, i)));
}
printf("]\n");
}
printf("\n\t]\n");
}
printf("]\n");
}
int main() {
int dim = 10;
size_t arraysize = sizeof (int) * dim * dim * dim;
int lookupindex = getindex(dim, 7, 5, 4); /* Numbers picked randomly */
int* tdarray = (int*) malloc(arraysize);
calloc(*tdarray, arraysize);
/* Below is test code and visualizations, all magic happens above.*/
if (*(tdarray + lookupindex) == 0) *(tdarray + lookupindex) = 7;
printf("tdarray[x:%d, y:%d, z:%d]:\t%d\n\n", 7, 5, 4, *(tdarray + lookupindex));
printarray(tdarray, dim);
printf("\n\n\n\n\n\n\n\n\n\n");
for (int i = 0; i < getindex(dim, 9, 9, 9) + 1; i++) *(tdarray + i) = i;
printarray(tdarray, dim);
free(tdarray);
}