简体   繁体   English

为什么堆栈中没有可变大小的数组?

[英]Why no variable size array in stack?

I don't really understand why I can't have a variable size array on the stack, so something like我真的不明白为什么我不能在堆栈上有一个可变大小的数组,所以像

foo(int n) {
   int a[n];
}

As I understand the stack(-segment) of part of the data-segment and thus it is not of "constant size".据我了解部分数据段的堆栈(-段),因此它不是“恒定大小”。

Variable Length Arrays(VLA) are not allowed in C++ as per the C++ standard.根据 C++ 标准,C++ 中不允许使用可变长度数组 (VLA)
Many compilers including gcc support them as a compiler extension, but it is important to note that any code that uses such an extension is non portable.许多编译器包括 gcc 支持它们作为编译器扩展,但重要的是要注意使用这种扩展的任何代码都是不可移植的。

C++ provides std::vector for implementing a similar functionality as VLA . C++ 提供std::vector来实现与VLA类似的功能。


There was a proposal to introduce Variable Length Arrays in C++11, but eventually was dropped, because it would need large changes to the type system in C++.有一个提议在 C++11 中引入可变长度数组,但最终被放弃了,因为它需要对 C++ 中的类型系统进行大量更改。 The benefit of being able to create small arrays on stack without wasting space or calling constructors for not used elements was considered not significant enough for large changes in C++ type system.能够在堆栈上创建小数组而不浪费空间或为未使用的元素调用构造函数的好处被认为对于 C++ 类型系统的大更改来说不够重要。

Note that the proposal was rejected and the following is no longer true.请注意,该提案被拒绝,以下内容不再正确。 It may be revived for a future version of C++ though.不过,它可能会在未来版本的 C++ 中恢复。

VLA as described in N3639 has been accepted in Bristol meeting and will become part of C++14, as well as a library counter-part "dynarray". N3639 中描述的 VLA 已在 Bristol 会议上被接受,并将成为 C++14 的一部分,以及库对应部分“dynarray”。 So using compiler with C++14 support we can start writing something like:因此,使用支持 C++14 的编译器,我们可以开始编写如下代码:

void func(int n)
{
    int arr[n];
}

Or use dynarray:或者使用动态数组:

#include <dynarray>

void func(int n)
{
    std::dynarray<int> arr(n);
}

I'll try to explain this with an example:我将尝试用一个例子来解释这一点:

Say you have this function:假设你有这个功能:

int myFunc() {
   int n = 16;
   int arr[n];
   int k = 1;
}

When the program runs, it sets the variables in this way onto the stack:当程序运行时,它以这种方式将变量设置到堆栈中:

- n @relative addr 0
- arr[16] @relative addr 4
- k @relative addr 64
TOTAL SIZE: 68 bytes

Let's say I want to resize arr to 4 elements.假设我想将 arr 调整为 4 个元素。 I'm going to do:我打算去做:

delete arr;
arr = new int[4];

Now: if i leave the stack this way, the stack will have holes of unused space.现在:如果我以这种方式离开堆栈,堆栈将有未使用空间的孔。 So the most intelligent thing to do is to move all the variables from one place to another in the stack and recompute their positions.所以最聪明的做法是将所有变量从堆栈中的一个位置移动到另一个位置并重新计算它们的位置。 But we are missing something: C++ does not set the positions on the fly, it is done only once, when you compile the program.但是我们遗漏了一些东西:C++ 不会即时设置位置,它只会在您编译程序时完成一次。 Why?为什么? It is straightforward: because there is no real need of having variable size objects onto the stack, and because having them would slow down all the programs when allocating/reallocating stack space.这很简单:因为没有真正需要将可变大小的对象放到堆栈上,并且因为在分配/重新分配堆栈空间时,拥有它们会减慢所有程序的速度。

This is not the only problem, there is another, even bigger one: When you allocate an array, you decide how much space it will take and the compiler can warn you if you exceed the available space, instead if you let the program allocate variable size arrays on your stack, you are opening breaches in security, since you make all the programs that use this kind of method vulnerable to stack-overflows.这不是唯一的问题,还有另一个更大的问题:当你分配一个数组时,你决定它需要多少空间,如果你超过可用空间,编译器会警告你,而不是让程序分配变量堆栈上的大小数组,您正在破坏安全性,因为您使所有使用这种方法的程序容易受到堆栈溢出的影响。

Simple answer: because it is not defined in the C++ standard.简单的回答:因为它没有在 C++ 标准中定义。

Not so simple answer: Because no one propsed something behaving coherently for C++ in that case.不是那么简单的答案:因为在这种情况下,没有人为 C++ 提出一致的行为。 From the standards POV there is no stack, it could be implemented totally differently.从标准 POV 来看,没有堆栈,它可以完全不同地实现。 C99 has VLAs, but they seem to be so complex to implement that gcc only finished the implementation in 4.6. C99 有 VLA,但它们实现起来似乎非常复杂,以至于 gcc 只在 4.6 中完成了实现。 I don't think many people will want to propose something for C++ and see compiler manufacturers struggle with it for many years.我不认为很多人会想要为 C++ 提出一些建议,并且看到编译器制造商多年来一直在为它而苦苦挣扎。

Stacks are fairly small, and their sizes can vary dramatically per architecture.堆栈相当小,并且它们的大小可能因架构而异。 The problem is that it is fairly easy to 'over-allocate' and cause a seg fault or write over memory owned by somebody else.问题是很容易“过度分配”并导致段错误或覆盖其他人拥有的内存。 Meanwhile, solutions to the problem (eg vector ) have existed for a long time.同时,该问题的解决方案(例如vector )已经存在很长时间了。

FWIW, I read Stroustrup say that he didn't want them, but I don't know which interview it was in. FWIW,我读到 Stroustrup 说他不想要他们,但我不知道这是在哪个采访中。

Because in C++ a static array needs a static constant size, so it is not allowed by the language.因为在 C++ 中,静态数组需要静态常量大小,所以语言不允许这样做。 Note that C99 does support vararrays at the stack, and some implementations support it under C++ as well as an extension.请注意,C99 确实支持堆栈中的可变数组,并且一些实现在 C++ 以及扩展下支持它。

Because the language specification says so.因为语言规范是这样说的。 Nothing else matters (and explaining with segments is terribly wrong for different reasons).其他都无关紧要(由于不同的原因,用段进行解释是非常错误的)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么在堆栈上分配任意大小的数组是不可能的? - Why is it impossible to allocate an array of an arbitrary size on the stack? 无法在具有恒定可变大小的类中创建堆栈分配数组 - Can't create a stack allocated array in a class with a constant variable size “变量周围的堆栈已损坏”。如何确定数组的大小? - ''Stack around the variable was corrupted". How to determine size of the array? c++ 可变大小堆栈数组在 function 中得到 const - c++ variable size stack array in function that get const 堆栈数组变量清除 - Stack array variable cleanup 为什么 Eigen 限制堆栈的大小? - Why Eigen limits size on the stack? 为什么在堆上迭代大型数组比在堆栈上迭代相同大小的数组更快? - Why is iterating a large array on the heap faster than iterating same size array on the stack? 声明大小为整数变量的数组时,为什么会出现编译器错误? - Why is there a compiler error, when declaring an array with size as integer variable? 可变大小的数组作为类成员:为什么要编译? - Variable size array as class member: why does it compile? 为什么这段代码在使用变量数组大小时不会产生错误? - Why doesn't this code generate an error on using a variable array size?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM