简体   繁体   English

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

[英]Allocating 2D array of dimensions read from file

I would like to read 2 numbers n,m from text file and then allocate a 2D array with n rows and m columns. 我想从文本文件中读取2个数字n,m ,然后分配具有n行和m列的2D数组。

Also, I would like to initialise the array in my main function in order to use it later in other functions, and do the reading and allocating in a different function, which I will call from the main function. 另外,我想在main函数中初始化数组,以便稍后在其他函数中使用它,并在另一个函数中进行读取和分配,这将从main函数中调用。

I know how to handle the reading, but I'm struggling with the array allocation. 我知道如何处理读数,但是我在数组分配方面苦苦挣扎。

I've read quite a few answer to similar questions here, but they didn't help me. 我在这里已经读了很多类似问题的答案,但是它们并没有帮助我。

I've wrote the following code, but not sure how to continue with it to get the desired result: 我已经编写了以下代码,但不确定如何继续执行以获得所需的结果:

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;
}

I thought perhaps I should first allocate a 2D array with calloc and then use realloc after reading n,m , but not sure if that's the best practise. 我想也许我应该先用calloc分配一个2D数组,然后在读取n,m之后再使用realloc ,但是不确定这是否是最佳实践。

What is the best practise to allocate a 2D array based on dimensions I read from text file? 根据从文本文件读取的尺寸分配2D数组的最佳实践是什么?

First the biggest goofs here: 首先是这里最大的钉子:

  • Your function doesn't have any types in the function signature -- this should be rejected by the compiler 您的函数的函数签名中没有任何类型 -编译器应拒绝此类型
  • a 2D array is not the same as an array of pointers 2D阵列是一样的指针数组
  • what should && mean? &&是什么意思? & is the address of something, its result can't have an address because it isn't stored anywhere, so this doesn't make sense &是某物的地址 ,其结果不能有地址,因为它没有存储在任何地方,因此这没有任何意义

If you want to dynamically allocate a real 2D array, you need to either have the second dimension fixed or use VLAs (which are optional in C11, but assuming support is quite safe) with a variable. 如果要动态分配实际的2D数组,则需要固定第二维或将VLA(在C11中是可选的,但假设支持非常安全)与变量一起使用。 Something like this: 像这样:

// dimensions in `x` and `y`, should be of type `size_t`
int (*arr)[x] = malloc(y * sizeof *arr);

In any case, the second dimension is part of the type, so your structure won't work -- the calling code has to know this second dimension for passing a valid pointer. 无论如何,第二维是该类型的一部分,因此您的结构将无法工作-调用代码必须知道此第二维才能传递有效的指针。


Hint: This first part doesn't apply to the question any more, OP forgot to mention he's interested in C90 only. 提示:第一部分不再适用于该问题,OP忘记提及他仅对C90感兴趣。 I added the appropriate tag, but leave the upper part of the answer for reference. 我添加了适当的标签,但将答案的上部留作参考。 The following applies to C90 as well: 以下内容也适用于C90:


You write int ** in your code, this would be a pointer to a pointer. 您在代码中写入int ** ,这将是一个指向指针的指针。 You can create something that can be used like a 2D array by using a pointer to a pointer, but then, you can't allocate it as a single chunk. 您可以通过使用指向指针的指针来创建可以用作 2D数组的对象,但是,您不能将其分配为单个块。

The outer pointer will point to an array of pointers (say, the "row-pointers"), so for each of these pointers, you have to allocate an array of the actual values. 外层指针将指向一个指针数组(例如,“行指针”),因此对于这些指针中的每一个,您都必须分配一个实际值数组。 This could look like the following: 看起来可能如下所示:

// 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);
}

Note on both snippets these are minimal examples. 请注意,这两个片段都是最小的示例。 For real code, you have to check the return value of malloc() each time . 对于真实代码, 您必须每次检查malloc()的返回值 It could return a null pointer on failure. 失败时可能返回空指针


If you want to have a contiguous block of memory in the absence of VLAs , there's finally the option to just use a regular array and calculate indices yourself, something like: 如果您想在没有VLA的情况下拥有连续的内存块,那么最后可以选择仅使用常规数组并自己计算索引,例如:

int *arr = malloc(x * y * sizeof *arr);

// access arr[8][15] when x is the second dimension:
arr[x*8 + 15] = 24;

This will generate (roughly) the same executable code as a real 2D array, but of course doesn't look that nice in your source. 这将生成(大致)与真实2D数组相同的可执行代码,但是在您的源代码中看起来当然不是那么好。


Note this is not much more than a direct answer to your immediate question. 请注意,这仅是直接回答您的直接问题。 Your code contains more goofs. 您的代码包含更多的傻瓜。 You should really enable a sensible set of compiler warnings (eg with gcc or clang , use -Wall -Wextra -pedantic -std=c11 flags) and then fix each and every warning you get when you move on with your project. 您应该真正启用一组合理的编译器警告(例如,使用gccclang ,使用-Wall -Wextra -pedantic -std=c11标志),然后修复在继续进行项目时收到的每一个警告。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM