该数组是静态的,但直到运行时才知道数组大小.这怎么可能?

y0s*_*1an 9 c++ arrays dynamic-memory-allocation dynamic-arrays

这让我困扰了一段时间.它是我(缺乏)理解静态和动态内存分配之间差异的核心.以下数组是一个普通的静态数组,它应该意味着内存是在编译期间分配的,对吗?然而,我已经设置好了,以便用户在运行时输入数组大小.

#include <iostream>
using namespace std;

int main() {
  cout << "how many elements should the array hold? ";
  int arraySize;
  cin >> arraySize;

  int arr[arraySize];

  for (int i = 0; i < arraySize; ++i)
    arr[i] = i * 2;

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

请注意,此程序中没有newdelete运算符.它在Xcode 4.2(默认的Clang编译器)以及我学校的UNIX服务器(GCC 4.4.5)中工作正常.arr在编译时创建数组时,编译器如何知道要分配多少内存?这只是我的编译器的侥幸,危险的代码,可能会破坏其他内存,或者这是合法的吗?

cel*_*chk 8

这是C++编译器的非标准扩展.请注意,在C中,与C++不同,从C99开始,这是正式支持的(即标准强制行为).在C++中,它不受支持,因为已经有问题的解决方案:使用std::vector而不是数组.

但是,数组不是使用静态内存分配(也不是动态内存分配),而是使用自动内存分配.自动变量在函数末尾自动释放(分配它们的内存区域称为堆栈,因为它上的分配和释放具有堆栈语义).要让数组使用静态内存分配,您必须放在static定义前面(请注意,全局或命名空间范围内的变量总是使用静态内存分配).但是,如果将变量设为静态,则会发现编译器不允许再使用非常量数组.

请注意,std::vector使用动态内存分配来存储其数据.因此,即使对于静态std::vectors ,您也可以使用非常量大小.


Kei*_*son 5

对于在函数内部声明的数组(或任何对象),内存在函数入口处分配(通常在堆栈上),并在函数返回时释放。该函数恰好main在这种情况下这一事实并不影响这一点。

\n\n

这:

\n\n
cin >> arraySize;\nint arr[arraySize];\n
Run Code Online (Sandbox Code Playgroud)\n\n

是一个“可变长度数组”(VLA)。问题是,C++ 不支持 VLA。从 1999 年 ISO C 标准 (C99) 开始,C 就这样做了,但这并不是 C++ 所采用的功能。

\n\n

您的编译器支持 C++ 中的 VLA 作为扩展。使用它们会使您的代码不可移植。

\n\n

(VLA 的一个问题是没有检测分配失败的机制;如果arraySize太大,则程序的行为是未定义的)。

\n\n

对于 gcc,编译时-pedantic会产生警告:

\n\n
warning: ISO C++ forbids variable length array \xe2\x80\x98arr\xe2\x80\x99\n
Run Code Online (Sandbox Code Playgroud)\n