C++中的自动变量

9
可能重复:在C ++中,为什么应该尽可能少地使用new 在C ++中,自动变量分配在堆栈还是堆上?
此外,我在7.9 - 堆栈和堆 中读到,堆栈上分配的所有内存都在编译时已知。这是真的吗?这是否意味着只有静态内存分配发生在堆栈上?
另外,请提供关于C ++中内存分配的完整解释性文本的链接和参考资料。

2
请参考这个问题来详细了解C++变量分配的原理。 - André Caron
6
C++是一种语言,而不是一种实现,所以它没有像“栈”这样的概念;这些东西留给编译器和特定平台。可能情况是具有自动存储期的每个对象都在堆上分配。然而,在实践中,它总是在栈上。但请记住,如果您真的需要了解这些信息,您将询问有关平台的信息,而不是关于C++的信息。让C++成为C++而不必担心。此外,不要从互联网学习C++,您应该获取一本好书。参考:https://dev59.com/_3RC5IYBdhLWcg3wK9yV。 - GManNickG
1
@GMan:实际上,自动变量并不总是在堆栈上。请看我的回答。 - Peter Alexander
@Peter:是的,也许“总是”这个词有点过于绝对了,但肯定大部分时间都是这样。寄存器是一种非常稀缺的资源。 - GManNickG
4个回答

19

C++并没有栈或堆的概念,对于编程语言来说这只是一种实现细节

尽管如此,在我所知道的所有实现中,都使用栈来管理本地变量的生命周期。然而,许多本地变量可能仅存在于寄存器中,从未接触过栈,有些本地变量甚至可能被完全优化掉。仅仅因为你声明了一个自动变量,并不意味着它会被放到栈上。

例如:

int main()
{
    int x = rand();
    int y = 2;
    cout << x << y << endl;
    return 0;
}

在这段代码中,启用优化后,变量y几乎肯定会被完全移除,变量x可能会分配自己的寄存器,但不太可能存在于堆栈中。


2
说得好。我讨厌“标准”警察跳出来,只是引用圣洁标准的语录。很棒的例子。 - Vinicius Kamakura
1
还有一个需要考虑的问题是,即使周围的对象具有自动存储期,成员变量可能仍然引用动态内存。如果vector<int> v;是自动的,因此很可能在"堆栈"上,v[0]仍然几乎肯定在"堆"上。 - Dennis Zickefoose
@Dennis:你说得对,一个向量的内容(可能)会在堆上,即使向量本身在栈上,但它的成员变量没有声明为自动存储(自动存储类只能用于局部变量,包括参数),所以它似乎与所提出的问题无关。 - Peter Alexander
1
是的,我同意。我的评论主要是为了扩展这个想法:“局部变量==>堆栈”并不是一个特别有用的简化,即使语言没有对堆栈实际存在的概念保持沉默。 - Dennis Zickefoose

2

自动(本地)变量不在堆上分配。它们要么存在于栈上,要么存在寄存器中。

是的,所有的栈分配都在编译时已知。

你提到的链接实际上是描述c ++如何处理内存的很好的资源。


2
是的,自动变量通常被分配在堆栈上(C++标准没有指定“堆栈”,但可以安全地假设如此)。
您可以使用堆栈来使用alloca()函数分配动态内存,但这不是很好的实践方法,有关详细信息,请参见此问题:为什么使用alloca()不被认为是良好的实践?

0
除了将一些本地变量定位在寄存器或堆栈上,一些编译器可能会选择重新使用特定的寄存器或内存,如果在编译时可以确定对象的可用寿命仅限于代码区域。
例如,
{
int a;
// do something with a

int b;
// do something with b but nothing with a
}

编译器会注意到a和b的大小相同,但在b的生命周期内a没有被使用。编译器将把a和b映射到同一块内存(堆栈或寄存器),节省一些空间。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接