为什么在C++内存管理中,“自动”和“动态”这些术语比“堆栈”和“堆”更受青睐?

53

根据stackoverflow上的许多问题和答案,我了解到引用生命周期由自动存储管理的对象比堆栈中的对象更好。

此外,动态分配的对象不应称为位于堆上,而应称为位于动态存储器上。

我知道有自动、动态和静态存储器,但从未真正理解自动-堆栈和动态-堆之间的区别。为什么前者更受欢迎?

我不是在问堆栈/堆的含义或内存管理的工作原理。我在问为什么首选术语“自动/动态存储器”而不是“堆栈/堆”。


我猜以下内容没有回答你的问题?https://dev59.com/jXRC5IYBdhLWcg3wG9Nb - NPE
1
@aix 并没有。或者至少它没有说明为什么一个术语比另一个更受欢迎,或者它们之间的区别。 - Luchian Grigore
可能是 C++ 中正确使用堆和栈的方法? 的重复问题。 - NPE
3
我一直认为这是因为标准没有规定自动存储期必须像堆栈一样实现。 - jrok
2
@LuchianGrigore:在编辑之前,我完全不清楚这个问题是关于术语而不是其他方面的。从评论/答案来看,其他人也完全不清楚。 - NPE
@aix 是的,在我的脑海中听起来更好。可能是因为我知道我想要问什么 :). 因此,我进行了编辑。我希望现在问题已经清楚了。 - Luchian Grigore
6个回答

59

Automatic向我传达了有关对象生命周期的信息:特别是它自动绑定到封闭作用域,并在该作用域退出时被自动销毁。

Dynamic告诉我,对象的生存期不会由编译器自动控制,而是在我的直接控制下。

Stack是一个一种容器类型的重载名称,并且与常见的 call ret 指令支持的相关流行指针协议相关。它并未详细说明对象的生命周期,除了通过与C中的对象生命周期的流行堆栈帧约定的历史联系之外。 还要注意,在某些实现中,线程本地存储在线程的堆栈上,但不限于任何单个函数的范围。

Heap再次是一个重载名称,表示一种排序容器类型或自由存储区管理系统。这不是所有系统上唯一的自由存储区,也没有具体说明使用new分配的对象的生命周期。


还有需要了解的是:并非所有系统都对非递归函数使用“堆栈”。此外,可以在“堆栈”上创建动态对象(我认为boost::variant就是这样做的)。 - Mooing Duck
还有哪些其他的免费存储器?实际上,“自由存储器”在什么意义上是免费的,而堆栈内存不是免费的? - AlwaysLearning
1
“Free store”只是指“可以分配的自由(内存)资源存储”。因此,任何系统特定的分配内存的方式,例如mmapsbrk,都可以计算在内。 - Useless
除了作为一种可选的实现细节外,栈内存一方面是由系统特定的分配器支持的普通内存(除非像 SPARC 那样它不是这样,或者不存在),另一方面是处理该内存的(解)分配方式。 - Useless

13
大多数实现使用堆栈来支持具有自动存储的对象。这不是标准要求的,但在大多数CPU架构上都很好用。
实现使用各种策略来支持具有动态存储期的对象。我不确定heap是描述现代内存分配器使用的最佳方式,但那似乎是“历史”术语。
因此,自动/动态存储是标准用于分类(“抽象”)对象寿命的术语。如果您想按照标准描述对象,则应使用这些正确的术语。
堆栈和堆是用于支持它们的(“具体”)实现技术。除非您正在谈论特定实现,否则使用这些术语不太正确。

9

从技术角度来说,栈/堆分配是实现细节,而自动/动态存储则是更通用的术语。标准本身并没有规定分配器必须使用栈/堆。因此,自动/动态是更合适的术语,尽管个人认为这种区分有点过于追求小节。


7
自动/动态存储术语更可取,因为这是标准所要求的。堆栈/堆是基于实现的,理论上可以用另一种方式实现。

6

在C++标准中出现了“静态存储期”,“自动存储期”和“动态存储期”的术语。

“堆栈”和“堆”这些术语用于指称标准库中的特性(stack<>make_heap()push_heap()等),这与存储期没有太大关系。


抱歉给你之前的回答点了个踩,我意识到问题有歧义。+1 - Luchian Grigore

1

栈和堆引入了与实现相关的概念,而术语“自动”和“动态”则更为通用。


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