问题描述
#include <stdio.h>
int main() {
int n = 0,i;
printf("Enter the size of array\n");
scanf("%d",&n);
int a[n];
for (i = 0; i < n; i++) {
a[i] = i + 1;
printf("%d,",a[i]);
}
}
我是否可以知道malloc()
和calloc()
与这段代码之间的区别,因为我想两者都可以满足需要?
解决方法
请注意,根据最新标准,VLA不是规范的强制性部分。分配器功能(malloc()
和系列)是分配内存的标准方法,其大小只有在运行时才知道。
引用C18
,第6.7.6.2/P4章
[...](可变长度数组是实现不需要支持的条件功能;请参阅 6.10.8.3。)
也就是说,由于VLA的性质,在使用VLA时还存在其他使用限制,它们的生存期在定义它们的范围内受到限制。例如,您不能从函数调用中返回在函数中定义的VLA,但是如果您使用分配器函数,则可以返回指针,因为指针的生存期一直到以编程方式释放(调用free()
)。
行
int a[n];
将a
声明为可变长度数组。 VLA是有用的,但有局限性:
- 不能使用
static
关键字或在文件范围内声明它们; - 它们不能在声明中初始化-例如,您不能写类似
int a[n] = {0};
; - 他们不能是
struct
或union
类型的成员; - 它们不能任意大;
- 它们不受普遍支持-在语言定义的1999年修订版中引入,在2011年修订版中变为可选;
- 它们在定义后无法调整大小-可变长度的“变量”仅表示它们的大小在一个定义到另一个定义之间是不确定的。
就像任何auto
变量一样,当您退出其封闭范围时,它们将不存在。
动态分配的内存比VLA具有一些优势:
- 在您显式
free
之前,内存一直保持分配状态; - 您可以分配任意大的内存块;
- 您可以根据需要调整分配的块的大小;
- 与VLA不同,
malloc
,calloc
和realloc
受任何托管实现的支持;
如果您需要的只是函数中的一些临时工作存储,您不知道它的大小,不需要太多,而且它们受支持,那么VLA是一个不错的选择,而更少比使用malloc
或calloc
更为混乱。