我不太明白为什么不能在堆栈上使用可变大小数组,例如:
foo(int n) {
int a[n];
}
据我所知,栈(段)是数据段的一部分,因此其大小不是“固定的”。
我不太明白为什么不能在堆栈上使用可变大小数组,例如:
foo(int n) {
int a[n];
}
据我所知,栈(段)是数据段的一部分,因此其大小不是“固定的”。
可变长度数组(VLA)在C ++标准中不被允许使用。
包括gcc在内的许多编译器支持它们作为编译器扩展,但需要注意的是,使用此类扩展的任何代码都是不可移植的。
C ++提供了 std :: vector 以实现与 VLA 类似的功能。
曾经有一个提案试图引入可变长度数组到C ++11中,但最终因为需要对C ++类型系统进行大量更改而被放弃。能够在堆栈上创建小型数组而不浪费空间或调用未使用元素的构造函数的好处被认为不足以证明必须对C ++类型系统进行大规模更改。
int myFunc() {
int n = 16;
int arr[n];
int k = 1;
}
- n @relative addr 0
- arr[16] @relative addr 4
- k @relative addr 64
TOTAL SIZE: 68 bytes
假设我想将arr调整为4个元素。我需要执行以下操作:
delete arr;
arr = new int[4];
这不是唯一的问题,还有另一个更大的问题: 当您分配数组时,您决定它将占用多少空间,编译器可以警告您是否超出了可用空间,但如果您让程序在堆栈上分配可变大小的数组,则会打开安全漏洞,因为您使得使用这种方法的所有程序都容易受到堆栈溢出的攻击。
delete arr;
?谁说这样是合法的?arr
不是一个指针。 - GManNickGarr
会自动分配内存。 - GManNickGvoid func(int n)
{
int arr[n];
}
或者使用dynarray:
#include <dynarray>
void func(int n)
{
std::dynarray<int> arr(n);
}
堆栈相对较小,其大小可能会因体系结构而大相径庭。问题在于很容易“过度分配”,导致段错误或写入其他人拥有的内存。与此同时,解决该问题的方案(如vector
)已经存在很长时间。
顺便说一下,我读到过 Stroustrup 说他并不希望它们存在,但我不知道是在哪次采访中。
template<int N> void foo(int (&arr)[N])
。 - Benjamin Lindley因为语言规范是这样规定的。其他什么都不重要(并且用段落进行解释是错的,原因有很多)。
std::vector
,所以它们不需要编译器来执行。另一方面,gcc和msvc都可以执行它。 - Mooing Duck