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)
请注意,此程序中没有new
或delete
运算符.它在Xcode 4.2(默认的Clang编译器)以及我学校的UNIX服务器(GCC 4.4.5)中工作正常.arr
在编译时创建数组时,编译器如何知道要分配多少内存?这只是我的编译器的侥幸,危险的代码,可能会破坏其他内存,或者这是合法的吗?
这是C++编译器的非标准扩展.请注意,在C中,与C++不同,从C99开始,这是正式支持的(即标准强制行为).在C++中,它不受支持,因为已经有问题的解决方案:使用std::vector
而不是数组.
但是,数组不是使用静态内存分配(也不是动态内存分配),而是使用自动内存分配.自动变量在函数末尾自动释放(分配它们的内存区域称为堆栈,因为它上的分配和释放具有堆栈语义).要让数组使用静态内存分配,您必须放在static
定义前面(请注意,全局或命名空间范围内的变量总是使用静态内存分配).但是,如果将变量设为静态,则会发现编译器不允许再使用非常量数组.
请注意,std::vector
使用动态内存分配来存储其数据.因此,即使对于静态std::vector
s ,您也可以使用非常量大小.
对于在函数内部声明的数组(或任何对象),内存在函数入口处分配(通常在堆栈上),并在函数返回时释放。该函数恰好main
在这种情况下这一事实并不影响这一点。
这:
\n\ncin >> 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
太大,则程序的行为是未定义的)。
对于 gcc,编译时-pedantic
会产生警告:
warning: ISO C++ forbids variable length array \xe2\x80\x98arr\xe2\x80\x99\n
Run Code Online (Sandbox Code Playgroud)\n