我想从文本文件中读取2个数字n,m
,然后分配一个包含n
行和m
列的2D数组。
此外,我想在我的main
函数中初始化数组,以便稍后在其他函数中使用它,并在另一个函数中进行读取和分配,我将从{{1 }}功能。
我知道如何处理读数,但是我在数组分配方面苦苦挣扎。
我在这里已经阅读了很多类似问题的答案,但是它们并没有帮助我。
我已经编写了以下代码,但是不确定如何继续执行以获得所需的结果:
main
我想也许我应该先用void func(int** array, int* rows, int* cols){
int n, m;
FILE *file;
fp = fopen("test.txt", "r");
if (file) {
/* reading numbers n and m */
*rows = n;
*cols = m;
**array = (int*)malloc(n * m * sizeof(int));
fclose(file);
}
}
int main() {
int rows, cols;
int** array;
func(&array, &rows, &cols);
return 0;
}
分配一个2D数组,然后在阅读calloc
之后使用realloc
,但不确定这是否是最佳实践。
根据我从文本文件读取的尺寸分配2D数组的最佳实践是什么?
答案 0 :(得分:3)
首先是这里最大的钉子:
&&
是什么意思? &
是某物的地址,其结果没有地址,因为它没有存储在任何地方,所以这没有道理如果要动态分配实际的2D数组,则需要固定第二维或将VLA(在C11中是可选的,但假设支持非常安全)与变量一起使用。像这样:
// dimensions in `x` and `y`, should be of type `size_t`
int (*arr)[x] = malloc(y * sizeof *arr);
无论如何,第二维是该类型的一部分,因此您的结构将无法工作-调用代码必须知道第二维才能传递有效的指针。
提示:第一部分不再适用于该问题,OP忘记提及他仅对C90感兴趣。我添加了适当的标签,但将答案的上部留作参考。以下内容也适用于C90:
您在代码中编写了int **
,这将是一个指向指针的指针。您可以通过使用指向指针的指针来创建可以像2D数组那样被使用的对象,但是您不能将其分配为单个块。
外部指针将指向一个指针数组(例如,“行指针”),因此对于这些指针中的每一个,您都必须分配一个实际值数组。看起来可能如下所示:
// dimensions again `x` and `y`
int **arr = malloc(y * sizeof *arr);
for (size_t i = 0; i < y; ++i)
{
arr[i] = malloc(x * sizeof **arr);
}
请注意两个摘录,这些都是最小的示例。对于真实代码,您必须每次检查malloc()
的返回值。失败时可能返回空指针。
如果您想在没有VLA的情况下拥有连续的内存块 ,最后可以选择只使用常规数组并自己计算索引,例如:
int *arr = malloc(x * y * sizeof *arr);
// access arr[8][15] when x is the second dimension:
arr[x*8 + 15] = 24;
这将生成(大致)与真实2D数组相同的可执行代码,但是在您的源代码中看起来当然不太好。
请注意,这仅是直接回答您的直接问题。您的代码包含更多的傻瓜。您确实应该启用一组明智的编译器警告(例如,使用gcc
或clang
,使用-Wall -Wextra -pedantic -std=c11
标志),然后修复在继续进行项目时收到的每一个警告。