Malloc是C中的2D数组

nin*_*zzo 3 c arrays malloc

每次我为2D数组分配内存时,我首先创建一个数组,int**然后使用for我为每个元素分配内存.

例如:

int ** arr = malloc(N*sizeof(int *));
for(i=0; i< N; i++) arr[i] = malloc(M*sizeof(int));
Run Code Online (Sandbox Code Playgroud)

不可能像以下那样分配内存:

int ** arr = malloc(N*sizeof(int[M]));
Run Code Online (Sandbox Code Playgroud)

要么

int ** arr = malloc(sizeof(int[N][M]));
Run Code Online (Sandbox Code Playgroud)

为了避免for?

flu*_*ter 10

int ** arr = malloc(N*sizeof(int[M])); 只是不正​​确的C代码,如果你通过像这样分配一次来模拟它:

int *arr = malloc(N*M*sizeof(int));
Run Code Online (Sandbox Code Playgroud)

添加访问权限arr[i*M + j],这类似于arr[I][j]第一种情况下的访问.

  • @Olaf冷静下来,没有可以用C的2D数组,OP想要为缓冲区分配一次以保存NxM整数. (5认同)
  • 此外,它根本不是"过时的",这是你今天看到的.这一切都取决于你的用例.奇怪的是,你可以将某种代码方式声称为"过时". (2认同)
  • @fluter:你可以!看我的回答。是的,它 _is_ 过时了。只是有太多的程序员认为C中没有多维数组。但仅仅因为“我们一直都是这样做的”并不意味着这是正确的方法。事实上,你的版本没有一个优点,但有很多缺点,例如:容易出错,更难理解,你必须自己追踪内部长度。 (2认同)

BLU*_*IXY 9

像这样 : int (*arr)[M] = malloc(sizeof(int[N][M]));

arr是指针int[M].

用得像 arr[0][M-1];

和 free(arr);

  • 更好 - `int (*arr)[M] = malloc( sizeof *arr * N);`。这样,如果 `arr` 的类型发生变化,你就不必修改 `sizeof` 表达式。 (2认同)
  • 然后是5.1.2.3/4中的这种语言:"在抽象机器中,所有表达式都按语义指定进行评估.**实际实现不需要评估表达式的一部分,如果它可以推断出它的值没有被使用并且不会产生任何副作用**(包括通过调用函数或访问易失性对象而导致的任何副作用)." 我认为这给了我们一个在指向VLA的指针上使用`sizeof`的方法. (2认同)

too*_*ite 5

你有一个“指向指针的指针”。那不能代表二维数组。

指向二维数组的指针的正确声明是

// number of elements in one row
#define COLS 10

// number of rows
#define ROWS 20

int (*array)[COLS];   // mind the parenthesis!
Run Code Online (Sandbox Code Playgroud)

这使得array一个指向COLS ints数组的指针。类型是`int (*)[COLS],顺便说一句。但你不需要类型,见下文。

要分配数组,您应该使用一维数组的标准分配:

array = malloc(sizeof(*array) * ROWS);   // COLS is in the `sizeof`

array = malloc(sizeof(int[ROWS][COLS])); // explicit 2D array notation
Run Code Online (Sandbox Code Playgroud)

使用哪种变体是个人风格。虽然第一个不包含冗余(考虑将 的声明更改array为 useINNER而不是COLS或将元素类型更改为float)。第二个一目了然,但在修改array.

至free:

free(array);
Run Code Online (Sandbox Code Playgroud)

  • 我很想知道反对者的反对意见是什么。 (3认同)
  • @MichaelPetch:我也是。但你不能与&lt;(好吧,你可能知道我会在这里写什么)&gt;争论。 (2认同)