关于c ++中的数组声明

时间:2014-12-02 08:09:04

标签: c++

int main(){

        int n;

        scanf("%d",&n);

        int a[n];
}

在上面,数组a []的空间在哪里,被分配?在堆栈还是堆?

3 个答案:

答案 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)

在执行项目之前,编译器必须知道代码中所有数组的大小。 程序运行时你无法分配它。