C + + ,免费存储 vs 堆

使用 new/delete的动态分配据说发生在 免费商店,< br > 上,而 malloc/free操作使用 一大堆

我想知道在实践中是否有实际的区别。
编译器是否区分这两个术语? (免费商店,而不是 new/malloc)

65944 次浏览

我不记得标准中曾经提到过堆这个词,除了在描述像 push_heap等堆函数时。所有动态分配都在空闲存储上执行。

术语“堆”也可能指特定的数据结构,但是在 C + + malloc、 free、 new 和 delete 操作的上下文中,术语“堆”和“ free store”或多或少可以互换使用。

参见 http://www.gotw.ca/gotw/009.htm; 它能比我更好地描述堆和免费存储之间的区别:

免费商店:

免费商店就是其中之一 分配/释放的动态内存区域 对象生存期可以是 少于存储时间 已分配的; 也就是说,可以自由存储对象 可以在没有 被立即初始化,并且可以 在没有记忆存在的情况下被摧毁 立即释放。在 分配存储的时间段 但是在对象的生命周期之外 存储器可能被访问和 通过虚空操纵,但是没有 原始物体的非静态 成员或成员函数可以是 访问,获取他们的地址, 或者被操纵。

堆积:

堆是另一个动态内存 区域,通过 malloc/free 分配/释放 以及它们的变体,请注意 默认的全局 new 和 delete 可能会以下列方式实施: 一个特定的 malloc 和 free 编译器,堆不同于 空闲存储器和分配在一个中的内存 区域不能被安全地释放 中分配的内存 堆可以用于类的对象 按位置分类-新建筑和 明确的破坏。如果这样使用, 关于免费存储对象生存期的说明 在这里同样适用。

迈克 · 科瓦尔的答案很好地涵盖了这个理论。然而,在实践中,它们几乎总是相同的内存区域——在大多数情况下,如果深入研究编译器的 new实现,您会发现它调用 malloc()

换句话说: 从机器的角度来看,堆和空闲存储是一回事。区别存在于编译器内部。

更令人困惑的是,在 C + + 出现之前,我们用“堆”来表示现在所谓的“免费存储”

对于 C + + 来说,空闲存储和堆之间的区别已经成为纯粹的概念。比如一个收集虫子的罐子,一个收集饼干的罐子。一个被贴上了标签,另一个又被贴上了标签。这个指定是为了让你明白,你永远不要把“ new”和“ delete”与“ malloc”、“ realloc”或“ free”(或相关的位水平集)混在一起。

在访谈中,可以这样说: “ newdelete使用免费存储,mallocfree使用堆; newdelete分别调用构造函数和析构函数,而 mallocfree不调用。”然而,你经常会听到内存段实际上是在同一个区域-然而,这可以是编译器特定的,也就是说,有可能两者都可以指定不同的内存空间作为池(但不确定为什么会这样)。

堆和免费存储不应该是可互操作的。 在有限的上下文中,比如使用 c + + 11标准库的 AVR 8位微控制器,它们甚至不能在同一个程序中使用。空闲存储和堆在相同的内存空间中进行分配,相互覆盖对方的结构和数据。 在这种情况下,Free store 与 Heap 不同,并且与 Heap 不兼容,因为“ new/delete Free store library”比“ Malloc/Free/realloc/calloc stack library”更简单(也更快) ,因此为 C + + 嵌入式程序员提供了巨大的内存使用增益(在只有512字节 RAM 的情况下)。

请参见 https://github.com/ambroise-leclerc/ETL/tree/master/libstd的8位 c + + 11/14标准库

免费存储是给程序的一个未分配堆内存池,程序在程序执行期间使用该堆内存池进行动态分配。 每个程序都提供了一个未分配的堆内存池,可以在执行期间使用。 这个可用内存池称为程序的空闲存储区。 分配的空闲存储内存未命名。