C++ 自由存储区是否等价于堆?

文章也发布在 听风过境的专栏html

“free store” VS “heap”

当我问你C++的内存布局时,你大概会回答:程序员

“在C++中,内存区分为5个区,分别是堆、栈、自由存储区、全局/静态存储区、常量存储区”。架构

若是我接着问你自由存储区与堆有什么区别,你或许这样回答:app

“malloc在堆上分配的内存块,使用free释放内存,而new所申请的内存则是在自由存储区上,使用delete来释放。”less

这样听起来彷佛也没错,但若是我接着问:ide

自由存储区与堆是两块不一样的内存区域吗?它们有可能相同吗?布局

你可能就懵了。操作系统

事实上,我在网上看的不少博客,划分自由存储区与堆的分界线就是new/delete与malloc/free。然而,尽管C++标准没有要求,但不少编译器的new/delete都是以malloc/free为基础来实现的。那么请问:借以malloc实现的new,所申请的内存是在堆上仍是在自由存储区上?htm

从技术上来讲,堆(heap)是C语言和操做系统的术语。堆是操做系统所维护的一块特殊内存,它提供了动态分配的功能,当运行程序调用malloc()时就会从中分配,稍后调用free可把内存交还。而自由存储是C++中经过new和delete动态分配和释放对象的抽象概念,经过new来申请的内存区域可称为自由存储区。基本上,全部的C++编译器默认使用堆来实现自由存储,也便是缺省的全局运算符new和delete也许会按照malloc和free的方式来被实现,这时藉由new运算符分配的对象,说它在堆上也对,说它在自由存储区上也正确。但程序员也能够经过重载操做符,改用其余内存来实现自由存储,例如全局变量作的对象池,这时自由存储区就区别于堆了。咱们所须要记住的就是:对象

堆是操做系统维护的一块内存,而自由存储是C++中经过new与delete动态分配和释放对象的抽象概念。堆与自由存储区并不等价。

问题的来源

再回过头来来看看这个问题的起源在哪里。最早咱们使用C语言的时候,并无这样的争议,很明确地知道malloc/free是在堆上进行内存操做。直到咱们在Bjarne Stroustrup的书籍中数次看到free store (自由存储区),说实话,我一直把自由存储区等价于堆。而在Herb Sutter的《exceptional C++》中,明确指出了free store(自由存储区) 与 heap(堆) 是有区别的。关于自由存储区与堆是否等价的问题讨论,大概就是从这里开始的:

Free Store
The free store is one of the two dynamic memory areas, allocated/freed by new/delete. Object lifetime can be less than the time the storage is allocated; that is, free store objects can have memory allocated without being immediately initialized, and can be destroyed without the memory being immediately deallocated. During the period when the storage is allocated but outside the object's lifetime, the storage may be accessed and manipulated through a void* but none of the proto-object's nonstatic members or member functions may be accessed, have their addresses taken, or be otherwise manipulated.

Heap
The heap is the other dynamic memory area, allocated/freed by malloc/free and their variants. Note that while the default global new and delete might be implemented in terms of malloc and free by a particular compiler, the heap is not the same as free store and memory allocated in one area cannot be safely deallocated in the other. Memory allocated from the heap can be used for objects of class type by placement-new construction and explicit destruction. If so used, the notes about free store object lifetime apply similarly here.

来源:http://www.gotw.ca/gotw/009.htm

做者也指出,之因此把堆与自由存储区要分开来,是由于在C++标准草案中关于这两种区域是否有联系的问题一直很谨慎地没有给予详细说明,并且特定状况下new和delete是按照malloc和free来实现,或者说是放过来malloc和free是按照new和delete来实现的也没有定论。这两种内存区域的运做方式不一样、访问方式不一样,因此应该被当成不同的东西来使用。

结论

  • 自由存储是C++中经过new与delete动态分配和释放对象的抽象概念,而堆(heap)是C语言和操做系统的术语,是操做系统维护的一块动态分配内存。

  • new所申请的内存区域在C++中称为自由存储区。藉由堆实现的自由存储,能够说new所申请的内存区域在堆上。

  • 堆与自由存储区仍是有区别的,它们并不是等价。

假如你来自C语言,从没接触过C++;或者说你一开始就熟悉C++的自由储存概念,而从没据说过C语言的malloc,可能你就不会陷入“自由存储区与堆好像同样,好像又不一样”这样的迷惑之中。这就像Bjarne Stroustrup所说的:

usually because they come from a different language background.

大概只是语言背景不一样罢了。

参考资料


游戏引擎架构 [Jason Gregory] 电子工业出版社


exceptional C++ [Herb Sutter]

相关连接:
http://www.gotw.ca/gotw/009.htm
http://zamanbakshifirst.blogspot.tw/2007/02/c-free-store-versus-heap.html

相关文章
相关标签/搜索