关于 C++ 中的数组声明

regarding array declaration in c++

本文关键字:数组 声明 C++ 关于      更新时间:2023-10-16
int main(){
        int n;
        scanf("%d",&n);
        int a[n];
}

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

如果你的编译器编译了它,它很可能会在堆栈上。在标准术语中,如果您想将其应用于实际上不符合标准的构造,它具有自动存储持续时间,这意味着您不必自己清理它,它将在范围结束时变得无效。

有一个VLA(可变长度数组(,一个由C构造的,它允许你拥有其维度仅在运行时已知的数组。通常,它们的工作方式类似于"函数"alloca,它将堆栈指针减少运行时已知的量,并"返回"指向它的指针。我把"函数"放在引号里,因为这样做需要一些普通函数范围语义没有提供的低级黑客。

VLA 在C++中不存在,因此你使用的是编译器扩展,该扩展中 VLA 的精确语义取决于编译器。由于这可能是 gcc,我将为您提供指向其文档相关部分的链接。

在 C11 标准中,它在 §6.7.6.2/4 中描述了实际上是什么使数组成为可变长度数组:

如果大小是整数常量表达式,并且元素类型具有 已知常量大小,数组类型不是可变长度数组 类型;否则,数组类型是可变长度数组类型。

然而在N3337(C++11草案(中,[dcl.array]说:

如果常量表达式 (5.19( 存在,则它应为 整数常量表达式及其值应大于零。

关于"可变长度数组"的语言完全缺失,因此它们在C++中不存在。

草案在 [basic.life] 中讨论了对象生存期。在 C 语言中,VLA 不能具有静态或线程存储持续时间。§6.2.4/7 然后说:

对于具有可变长度数组类型的此类对象,其 生存期从对象的声明一直延伸到执行 程序离开声明的范围。35( 如果 以递归方式输入范围,创建对象的新实例 每次。对象的初始值不确定。

GCC 允许 VLA 作为扩展C++,模仿相同的语义:

ISO C99 中允许使用可变长度自动阵列,并作为 扩展 GCC 以 C90 模式和C++接受它们。这些数组是 声明与任何其他自动数组一样,但长度为 不是一个恒定的表达式。存储分配在 声明和解除分配时块范围包含 声明退出。

Clang还允许VLA与某些限制兼容。

因此,VLA 很可能是在堆栈上分配的。

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