不使用 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]
一旦知道row
和col
的值,编译后的代码在自动存储区(通常称为"the stack")做这个分配是没有问题的).
how it is able to make machine code and set the address space for the program?
编译器存储 row
和 col
的值,供其生成的机器代码内部使用。引用 a[i][j]
的指令查找大小、进行数学运算、添加偏移量并获取地址,就好像 row
和 col
在编译时已知。
该功能确实改变了其他一些事情 - 例如,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));
我很惊讶地看到这段代码能正常工作。我不明白为什么
#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]
一旦知道row
和col
的值,编译后的代码在自动存储区(通常称为"the stack")做这个分配是没有问题的).
how it is able to make machine code and set the address space for the program?
编译器存储 row
和 col
的值,供其生成的机器代码内部使用。引用 a[i][j]
的指令查找大小、进行数学运算、添加偏移量并获取地址,就好像 row
和 col
在编译时已知。
该功能确实改变了其他一些事情 - 例如,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));