不使用 malloc 创建动态数组

Creating Dynamic Array without malloc

我很惊讶地看到这段代码能正常工作。我不明白为什么

#include<stdio.h>
int main(){
  int row,col,i,j;
  scanf("%d %d",&row,&col);
  int a[row][col];
  for(i=0;i<row;i++)
      for(j=0;j<col;j++)
           scanf("%d",&a[i][j]);
   for(i=0;i<row;i++){
      for(j=0;j<col;j++)
           printf("%d ",a[i][j]);
       printf("\n");
   }
}

既然C是一种编译型语言,那么它是如何为数组a[row][col]分配内存的呢?既然在编译的时候不知道行和列的值,那么如何才能生成机器码并为程序设置地址space呢?为什么这是作为一种解释器语言工作的,如果这是一种创建动态数组的方法,那么为什么我们被教导使用 malloc 在 C 中创建动态数组。

That's feature of C99。无论如何使用 malloc 的原因是它分配 space 不是在堆栈上,而是在堆上 - 而堆是应该存储 'heavy' 数据的地方,因为堆栈 space 受到严格限制。比那更多的;未能进行堆栈分配通常会使程序崩溃 - 而使用 malloc returns 分配 NULL 指针时,它允许您以优雅的方式继续。

Variable-length 自 C99 以来,数组一直是 C 的标准功能。

How it is allocating memory for the array a[row][col]

一旦知道rowcol的值,编译后的代码在自动存储区(通常称为"the stack")做这个分配是没有问题的).

how it is able to make machine code and set the address space for the program?

编译器存储 rowcol 的值,供其生成的机器代码内部使用。引用 a[i][j] 的指令查找大小、进行数学运算、添加偏移量并获取地址,就好像 rowcol 在编译时已知。

该功能确实改变了其他一些事情 - 例如,sizeof 不再是纯粹的 compile-time 操作,因为 VLA 的大小需要在 run-time 处计算。

why are we taught to use malloc for creating dynamic array in C.

malloc 比 VLA 更灵活。例如,您可以从函数 return malloc 创建数组,而 VLA 会在函数完成后立即自动释放。此外,malloc 不太可能 运行 您的程序内存不足,因为动态存储区域比自动存储区域更大。

例如,如果您尝试为您的程序输入 2000 2000,它很可能会崩溃。然而,分配相同数量的内存没有问题 malloc:

int (*a)[col] = malloc(row*col*sizeof(int));