理解 C 中的内存分配有点困难

can*_*ife 4 c malloc memory-management dynamic-memory-allocation

所以我正在学习如何用 C 语言编程,并开始学习动态内存分配。我所知道的是,您的程序并非总是知道它在运行时需要多少内存。

我有这个代码:

#include <stdio.h>

int main() {
   int r, c, i, j;
   printf("Rows?\n");
   scanf("%d", &r);
   printf("Columns?\n");
   scanf("%d", &c);

   int array[r][c];
   for (i = 0; i < r; i++)
      for (j = 0; j < c; j++)
         array[i][j] = rand() % 100 + 1;

   return 0;
}
Run Code Online (Sandbox Code Playgroud)

因此,如果我想创建一个二维数组,我只需声明一个并将数字放在括号中即可。但在这段代码中,我询问用户他们想要多少行和列,然后用这些变量声明一个数组,然后用随机整数填充行和列。

所以我的问题是:为什么我不必使用像malloc这里这样的东西?我的代码不知道在运行时要放入多少行和列,那么为什么我可以使用当前代码访问该数组?

Joh*_*ger 6

所以我的问题是:为什么我不必在这里使用类似 malloc 的东西?我的代码不知道在运行时要放入多少行和列,那么为什么我可以使用当前代码访问该数组?

您正在使用称为“可变长度数组”的 C 功能。它在 C99 中作为强制功能引入,但在 C11 和 C18 中对其支持是可选的。这种动态分配的替代方案存在一些局限性,其中包括:

  • 由于该功能是可选的,因此无条件依赖该功能的代码无法移植到不支持该功能的实现中

  • 支持VLA的实现通常将本地VLA存储在堆栈上,如果在运行时数组维数很大,则很容易产生堆栈溢出。(动态分配的空间通常对此类问题不太敏感。大型、固定大小的自动数组也可能是一个问题,但这些问题的潜在问题在源代码中是显而易见的,并且在运行过程中不太可能逃避检测。测试。)

  • 程序在声明之前仍然需要知道数组的维度,并且声明时的维度在数组的生命周期内是固定的。与动态分配的空间不同,VLA 无法调整大小。

  • 有些上下文可以容纳普通的固定长度数组,但不能容纳 VLA,例如文件范围变量。