这可能是一个基本问题,但我想为结构的 3 维数组分配内存。 我正在尝试从文件中读取 double 并希望存储在结构中。第一行是 block 号(这里不相关,因为它总是1),第二行分别表示X,Y和Z坐标中的网格点数。在这种情况下,X 方向有 10 个点,Y 方向有 5 个点,Z 方向有 1 个点。从第三行开始,是每个点的 X、Y、Z 坐标,它们是我想要读取的 double 。首先是所有 X 分量(即 10*5*1 x 坐标,然后是类似的 Y 和 Z)。文件格式是这样的:
1
10 5 1
0.000000e+00 1.111111e+00 2.222222e+00 3.333333e+00
4.444445e+00 5.555555e+00 6.666667e+00 7.777778e+00
8.888889e+00 1.000000e+01 0.000000e+00 1.111111e+00
2.222222e+00 3.333333e+00 4.444445e+00 5.555555e+00
6.666667e+00 7.777778e+00 8.888889e+00 1.000000e+01
0.000000e+00 1.111111e+00 2.222222e+00 3.333333e+00
4.444445e+00 5.555555e+00 6.666667e+00 7.777778e+00
8.888889e+00 1.000000e+01 0.000000e+00 1.111111e+00
2.222222e+00 3.333333e+00 4.444445e+00 5.555555e+00
6.666667e+00 7.777778e+00 8.888889e+00 1.000000e+01
0.000000e+00 1.111111e+00 2.222222e+00 3.333333e+00
4.444445e+00 5.555555e+00 6.666667e+00 7.777778e+00
8.888889e+00 1.000000e+01...and so on...
我可以读取前 4 个整数,因此我知道我希望存储数据的点数。然后我使用 malloc 函数分配内存并将数据存储在变量中。当我执行程序时,它读取整数但无法读取 double 。我犯了什么错误?
这是我的代码:
#include <stdio.h>
#include <stdlib.h>
typedef struct{
double x,y,z;
}Mesh;
int main(void)
{
int nblocks, IMAX, JMAX, KMAX;
Mesh ***grid;
FILE *mesh = fopen("test.x","r");
fscanf(mesh,"%i %i %i %i",&nblocks,&IMAX,&JMAX,&KMAX);
printf("%i %i %i %i\n",nblocks,IMAX,JMAX,KMAX);
grid = malloc(sizeof(Mesh)*nblocks*IMAX*JMAX*KMAX);
fscanf(mesh,"%lf",&grid[0][0][0].x);
printf("%lf\n",grid[0][0][0].x);
fclose(mesh);
return 0;
}
程序在编译时没有给出任何错误,但它没有读/写我存储在结构的 x 变量中的变量。 (如果可行,我可以将其放入循环中以读取我未在此处完成的所有值。)
如果我在读入 IMAX,JMAX,KMAX
后定义 Mesh grid[IMAX][JMAX][KMAX]
,我会得到正确的输出。但想知道指针的工作方式。
谢谢, 普拉纳夫
最佳答案
问题是您将网格定义为指向结构指针的指针,但您认为您有一个连续元素的三维数组。
错误说明
以下数组:
Mesh array[10][5][1]; // what you would like to manage dynamically
会像这样存储在内存中:
+----+----+----+----+----+----+----+----+----+----+----+----+-----
|A000|A010|A020|A020|A030|A040|A100|A110|A120|A120|1030|A140|....
+----+----+----+----+----+----+----+----+----+----+----+----+-----
但是下面的指针指向指针
Mesh ***grid; // How you decladed it
就像这样管理:
grid--> +--+--+--+--+--+--+--+
| 0| 1| 2|........| 9| some pointers to "pointers to struct"
+--+--+--+--+--+--+--+
grid[0] |
+---> +--+--+------+
| 1| 2| .... | some pointers to struct
+--+--+------+
grid[0][0] |
+---> +--+--+------+
| 1| 2| .... | some struct
+--+--+------+
grid[0][0][0] |
+---> +----+----+----+----
|A000|A010|A020|... some struct
+----+----+----+----
您的 malloc()
分配了一组连续的 IMAX*JMAX*KMAX 结构元素。实际上,它就像一个一维数组,因为 malloc() 和您的编译器对维度及其各自的大小一无所知。
但是当您编写 grid[0] 时,您的代码会查看 grid 指向的地址并期望在那里找到一个指针(但它只是未初始化的结构)等等。所以你可能会在内存中的一个随机位置写入并得到一个段错误。
解决方案
您必须将网格作为结构的一维数组进行管理,并在您的代码中明确组织索引。
所以声明:
Mesh *grid;
每当您想到网格的元素 [i][j][k] 时,请写:
grid[(i*JMAX+j)*KMAX+k]
杂项说明:
您可以使用 calloc(IMAX*JMAX*KMAX, sizeof(Mesh))
因为它清楚地表明它是一个数组,并且内存块设置为 0。
顺便说一下,(可能你的真实代码中已经有了它)作为反射总是检查分配是否成功,并在你不再需要它时预见一个 free() 。
关于c - 将 malloc 用于结构的多维数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25512863/