Jer*_*fin 11
其他人已经给出了关于堆的好答案,所以我将单独留下.
一些实现(例如,在IBM大型机上)不使用堆栈,因为大多数人会想到它,原因很简单,硬件不支持它.相反,当您调用函数时,会从堆(它们的版本)中分配激活记录(即本地,参数和返回地址的空间).这些激活记录内置在链表中.
从纯粹抽象的角度来看,这肯定是一个堆栈 - 它支持后进先出语义,就像任何其他堆栈一样.你必须非常抽象地看它,把它称为堆栈.如果你向人们展示链接在一起的内存块图表,我认为大多数程序员都会将其描述为链表是安全的.如果你推动它们,我认为大多数人会判断它是"是的,你可以像堆栈一样使用它,但它仍然是一个链表."
C++标准没有提到有关堆栈或堆的任何内容
实际上它确实 - 只是没有用那些语言,也没有说明如何实现堆栈和堆.
在C++ 03中有三种变量:
new
表达式创建的,并用a来销毁delete
.对象本身是无范围的,因为它们的生命周期不受它们被new
编辑的上下文的约束.当然,对这些对象的即时指针是作用域.指针具有自动或很少(通常是错误的)静态存储持续时间."Stack"和"Heap"实际上就是后来的第二种两种类型的对象.它们是与平台相关的实现细节,可实现语言要求.
所以,从技术上讲,你是对的.标准没有说明堆和堆栈.但它确实说了不少关于存储时间的不同口味需要一些在真实的平台类型的实现.在大多数现代PC类型硬件上,这是作为堆和堆栈实现的.可以在不使用堆或堆栈的情况下在平台上实现不同类型的存储持续时间吗?一切皆有可能 - 我想它可以.但无论实现最终如何,它可能具有与两者中的至少一个类似的特征.
除此之外,还需要考虑标准要求自动和动态存储持续时间.任何不符合这两个要求的语言实现都不是C++.它可能很接近,但它实际上不是C++.
对于小型编程环境,例如基于 8K Atmel 微处理器的arduino 平台(现在有 32K 或更多),没有实现堆,并且库没有定义新的运算符。所有对象都是静态创建的或在堆栈上创建的。您失去了标准库的优势,但能够使用面向对象的语言对非常小的平台进行编程 - 例如,创建类来表示配置为特定输出模式或串行端口的引脚,创建该类的对象给它引脚号,然后调用该对象上的函数,而不必将引脚号传递给您的例程。
如果您new
在 arduino 上使用,您的程序会编译但不会链接 - 编译器是针对 avr 指令集的 g++,真正的 C++ 编译器也是如此。如果您选择提供自己的实现,则可以这样做,但在大多数情况下,在如此小的占地面积上提供实现的成本是不值得的。