我还是C,malloc和所有爵士乐的新手,所以我决定写这个以学习更多技巧。我的想法是,我正在从一个文件中读取一堆int并将它们放入矩阵(2d数组)中。文件的开头说明有多少行和列,所以它读取这些数字并使用malloc来设置二维数组。
int read_matrix(FILE *mat, int ***Z, int *x, int *y)
{
int i = 0;
int x_temp = 0;
int y_temp = 0;
if (fscanf(mat, "%d %d", &(*x), &(*y)) == EOF){
printf("File is not big enough to contain a matrix\n");
return -1;
}
printf("About to malloc %d\n", *x);
*Z = (int**) malloc(*x * sizeof(int*));
while (i < *x) {
printf("mallocing %d\n", i);
*Z[i] = (int*) malloc(*y * sizeof(int));
printf("malloced\n");
++i;
}
printf("Malloc complete\n");
/*Other unimportant code*/
}
输出显示:
About to malloc 3
mallocing 0
malloced
mallocing 1
Segmentation fault
因此,除了Z中的一个int **之外,它没有任何内容。我想?
我是C的新手,所以我不确定我是否犯了一些小错误,或者我是否真的错过了这一切。有什么想法吗?谢谢!
答案 0 :(得分:3)
[]
运算符比一元*
运算符绑定得更紧密。尝试将*Z[i]
更改为(*Z)[i]
并查看您的代码是否符合规定。
作为旁注,在C中malloc一个(sizex * sizey)大小的单个数组,对于矩阵然后将其索引为arr [x * sizey + y]或arr [y * sizex + X]。这更接近于模仿语言对静态数组的作用(例如,如果你声明int foo[10][10]
,所有100个整数在内存中是连续的,并且没有一个存储10个int *的列表。
答案 1 :(得分:2)
我同意Walter和AndreyT。这只是一些额外的信息。
请注意,只有两个malloc()
次调用而不是*x + 1
- 一个用于int
s本身的大块,一个用于行索引。
*Z = malloc(*x * sizeof (*Z)[0]);
(*Z)[0] = malloc(*x * *y * sizeof (*Z)[0][0]);
for (i = 1; i < *x; i++) {
(*Z)[i] = (*Z)[0] + i * *y;
}
答案 2 :(得分:1)
正如沃尔特在答案中正确指出的那样,它应该是(*Z)[i] = ...
,而不是*Z[i] = ...
。
最重要的是,我建议摆脱源代码中出现的dereference / typecast地狱。不要投射malloc
的结果。不要在sizeof
下使用类型名称。表达如下
*Z = malloc(*x * sizeof **Z);
...
(*Z)[i] = malloc(*y * sizeof *(*Z)[i]);
将使您的代码类型独立且更具可读性。
另一个问题是地球上的哪些内容让您在&(*x)
中使用fscanf
。这是一种奇怪的编码标准吗?