int main(){
int n;
scanf("%d",&n);
int a[n];
}
在上面,数组a []的空间在哪里,被分配?在堆栈还是堆?
答案 0 :(得分:3)
如果您的编译器编译它,它很可能会在堆栈上。按照标准的说法,如果您希望将其应用于实际上不符合标准的构造,则它具有自动存储持续时间,这意味着您不必自行清理它,并且在范围的最后它将变为无效。 / p>
你所拥有的是一个VLA(可变长度数组),一个来自C的结构,它允许你拥有只在运行时知道其尺寸的数组。通常,它们的工作方式类似于“函数”alloca
,它将堆栈指针减少了运行时已知的量,并“返回”指向它的指针。我把“函数”放在引号中,因为这样做需要一些低级hackery,这是普通函数作用域语义所没有的。
V ++中不存在VLA,因此您使用的是编译器扩展,并且该扩展中的VLA的精确语义取决于您的编译器。由于这可能是gcc,我会给你一个the relevant part of its documentation链接。
答案 1 :(得分:2)
在C11标准中,它在§6.7.6.2/ 4中描述了实际使数组成为可变长度数组的原因:
如果大小是整数常量表达式且元素类型具有 在已知的常量大小中,数组类型不是可变长度数组 类型;否则,数组类型是可变长度数组类型。
然而在N3337(C ++ 11草案)中,[dcl.array]说:
如果存在常量表达式(5.19),则它应为a 积分常数表达式及其值应大于零。
关于“可变长度数组”的语言完全缺失,因此它们在C ++中不存在。
该草案讨论了[basic.life]中的对象生命周期。在C中,VLA不能具有静态或线程存储持续时间。然后§6.2.4/ 7说:
对于这样一个具有可变长度数组类型的对象,它的 生命周期从对象的声明延伸到执行 程序离开了声明的范围。 35)如果 以递归方式输入范围,创建对象的新实例 每一次。对象的初始值是不确定的。
GCC,它允许C ++中的VLA作为extension,模仿相同的语义:
ISO C99允许使用可变长度自动数组,并且作为 扩展GCC在C90模式和C ++中接受它们。这些数组是 声明像任何其他自动数组,但长度是 不是一个恒定的表达。存储分配在 当块范围包含时,声明和释放 声明退出。
Clang还允许VLA与某些restrictions兼容。
因此,很可能在堆栈上分配了VLA。
答案 2 :(得分:0)
在执行项目之前,编译器必须知道代码中所有数组的大小。 程序运行时你无法分配它。