分配从文件读取的二维尺寸数组

时间:2018-07-28 08:01:24

标签: c multidimensional-array c89

我想从文本文件中读取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数组的最佳实践是什么?

1 个答案:

答案 0 :(得分:3)

首先是这里最大的钉子:

  • 您的函数在函数签名中没有任何 types -编译器应拒绝此函数
  • 2D数组与指针数组
  • 相同
  • &&是什么意思? &是某物的地址,其结果没有地址,因为它没有存储在任何地方,所以这没有道理

如果要动态分配实际的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数组相同的可执行代码,但是在您的源代码中看起来当然不太好。


请注意,这仅是直接回答您的直接问题。您的代码包含更多的傻瓜。您确实应该启用一组明智的编译器警告(例如,使用gccclang,使用-Wall -Wextra -pedantic -std=c11标志),然后修复在继续进行项目时收到的每一个警告。