(转)C++ 自由存储区是否等价于堆?
“free store” VS “heap”
当我问你C++的内存布局时,你大概会回答:
“在C++中,内存区分为5个区,分别是堆、栈、自由存储区、全局/静态存储区、常量存储区”。
如果我接着问你自由存储区与堆有什么区别,你或许这样回答:
“malloc在堆上分配的内存块,使用free释放内存,而new所申请的内存则是在自由存储区上,使用delete来释放。”
这样听起来似乎也没错,但如果我接着问:
自由存储区与堆是两块不同的内存区域吗?它们有可能相同吗?
你可能就懵了。
事实上,我在网上看的很多博客,划分自由存储区与堆的分界线就是new/delete与malloc/free。然而,尽管C++标准没有要求,但很多编译器的new/delete都是以malloc/free为基础来实现的。那么请问:借以malloc实现的new,所申请的内存是在堆上还是在自由存储区上?
从技术上来说,堆(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.
作者也指出,之所以把堆与自由存储区要分开来,是因为在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.
大概只是语言背景不同罢了。
(转)C++ 自由存储区是否等价于堆?的更多相关文章
- C++ 自由存储区是否等价于堆?
"free store" VS "heap" 当我问你C++的内存布局时,你大概会回答: "在C++中,内存区分为5个区,分别是堆.栈.自由存储区.全 ...
- C++中内存布局 以及自由存储区和堆的理解
文章搬运自https://www.cnblogs.com/QG-whz/p/5060894.html,如有侵权请告知删除 当我问你C++的内存布局时,你大概会回答: "在C++中,内存区分为 ...
- free store VS heap(自由存储区VS堆)
1. free store VS heap free store (自由存储区)和 heap (堆),在C/C++中经常会遇到.他们是否有区别呢? 偶最早发现这两个概念性问题是在<Excepti ...
- C++内存分配方式详解——堆、栈、自由存储区、全局/静态存储区和常量存储区
栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量的存储区.里面的变量通常是局部变量.函数参数等.在一个进程中,位于用户虚拟地址空间顶部的是用户栈,编译器用它来实现函数的调用.和堆一样 ...
- 转:内存区划分、内存分配、常量存储区、堆、栈、自由存储区、全局区[C++][内存管理][转载]
内存区划分.内存分配.常量存储区.堆.栈.自由存储区.全局区[C++][内存管理][转载] 一. 在c中分为这几个存储区1.栈 - 由编译器自动分配释放2.堆 - 一般由程序员分配释放,若程序员不释放 ...
- C++内存分区:堆、栈、自由存储区、全局/静态存储区和常量存储区
日志 ...
- 【校招面试 之 C/C++】第14题 C++ 内存分配方式详解——堆、栈、自由存储区、全局/静态存储区和常量存储区(堆栈的区别)
栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量的存储区.里面的变量通常是局部变量.函数参数等.在一个进程中,位于用户虚拟地址空间顶部的是用户栈,编译器用它来实现函数的调用.和堆一样 ...
- 内存区划分、内存分配、常量存储区、堆、栈、自由存储区、全局区[C++][内存管理][转载]
http://www.cnblogs.com/JCSU/articles/1051579.html 一. 在c中分为这几个存储区1.栈 - 由编译器自动分配释放2.堆 - 一般由程序员分配释放,若程序 ...
- (转)C++内存分配方式详解——堆、栈、自由存储区、全局/静态存储区和常量存储区
程序在内存有五个存在区域: A:动态区域中的栈区 B:动态区域中的栈区 C:静态区域中:全局变量 和静态变量 (这个区域又可以进一步细分为:初始化的全局变量和静态变量 以及 未初始 ...
随机推荐
- 关于重绘and重排
在研究CSS3动画性能的时候,看到了重排两个字. 突然想到自己虽然听说过这么个东东,但一直也没深入研究之. 趁着当下正好有研究的劲头,所以一不做二不休,把这个point也给学习了. 同样是一番查找资料 ...
- 配置文件详解和核心api讲解
一.配置文件详解 1.映射文件详解 1.映射配置文件的位置和名称没有限制. -建议:位置:和实体类放在统一目录下. 名称:实体类名称.hbm.xml. 2.在映射配置文件中,标签内的name属 ...
- Getting over the dangers of rm command in Linux---reference
reference:http://www.coolcoder.in/2014/01/getting-over-dangers-of-rm-command-in.html When we want to ...
- 我该不该学习C语言
这几天把c语言过了一遍,基本上算是入门了,常用语法.函数的使用.c语言是比较古老的语言了,很多系统的底层.工业控制软件都是使用C语言编写,过一遍之后觉得c语言屹立不倒是有原因.c程序员有一句话:使用c ...
- ReSharper+Devexpress 删除光标之后的换行
echo. >"$(ProjectDir)\Properties\licenses.licx" 官方链接
- wxss无法调用本地资源图片
微信小程序中,wxss中不能调用本地资源图片作为背景图片,奇怪的是在微信开发者工具中可以调用,但是到了真机预览的时候发现并不行,有的电脑上的连微信开发者工具里也不可以调用. 原因在于小程序上传的是代码 ...
- 此请求的URL的长度超过配置的maxUrlLength值
aps.net 网站的url长度默认限制为260个字符. 修改web.config即可 <system.web> <httpRuntime maxUrlLength=" ...
- 关于asp.net假分页的删除操作的随笔
作为一个新人,上周负责优化一个后台管理系统,遇到一个问题:点击删除按钮之后,页面又回到了第一页. 而我需要达到的效果是:点击了删除按钮之后,原来是那一页,删除后还是在那一页. 由于项目是已经验收了的, ...
- 前端(五):JavaScript面向对象之内建对象
一.数据类型 js中数据类型分为两种,原始数据累次能够和引用数据类型. 1.原始数据类型 Undefined.Null.Boolean.Number.String是js中五种原始数据类型(primit ...
- UNION ALL 视图 'ImprotHIS2012.dbo.ImportHISData' 不可更新,因为没有找到分区依据列。 Severity 16 State 12
-- 3 更正措施,使约束check一次 Alter Table ImprotHIS_Bak_2011.dbo.ImportHISData with check Check Constraint al ...