C/C++ 内存分区以及自由存储区和堆的区别

作者: 骇客HK

出处:https://www.cnblogs.com/ruanraun/p/Heap.html

 

C/C++编译的程序占用的内存分区

1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数名局部变量的名等。其操作方式类似于数据结构中的

2、堆区(heap)— 由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表

3、全局/静态存储区 —全局变量和局部静态变量的存储是放在一块的(在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分)。程序结束后由系统释放。

4、常量存储区 — 常量字符串就是放在这里的,正常情况不允许修改,程序结束后由系统释放 。

5、程序代码区 — 存放函数体的二进制代码。

 

自由存储区(free store) 和 堆区 (heap) ?

我参考了网上很多资料和文章关于C/C++的内存分区都把自由存储区和堆区单独区分了开来,很多C/C++内存分区分类都是如下分类:

1、栈区 —  (同上)

2、堆区 —  由malloc等分配的内存块,它是用free来结束自己的生命的。 

3、自由存储区 — 由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。

4、全局/静态存储区 —  (同上)

5、常量存储区 —   (同上)

 

我对第二种分类方式产生了如下疑问:自由存储区与堆区的内存区域有可能相同吗?

很多文章一般用来划分自由存储区与堆的分界线就是new/delete与malloc/free。而C语言很明确地知道malloc/free是在堆上进行内存操作。那么new/delete申请销毁的区域是否也在堆上呢?

 

我随后通过查阅相关的资料和文章,最终还是找到了答案:

里面写到

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.

Free Store

自由存储是两个动态内存区域之一,由NeX/Delphi分配/释放。对象生存期可以小于存储分配的时间;也就是说,空闲存储对象可以在不立即初始化的情况下分配内存,并且可以在没有立即释放内存的情况下被销毁。在存储被分配但在对象的生命周期之外的期间,可以通过void*访问和操作存储,但是可以访问原始对象的非静态成员或成员函数中的任何一个,不具有它们的地址,或者以其他方式操作。

Heap

堆是另一个动态内存区域,由MALOC/FILE和它们的变体分配/释放。请注意,虽然默认全局全局和删除可以用Malc和特定编译器自由实现,但堆与自由存储区不相同,并且在一个区域中分配的内存不能在另一个区域安全地释放。从堆中分配的内存可以通过放置新构造和显式销毁来使用类类型的对象。如果使用的话,关于自由存储对象寿命的注释在这里同样适用。

所以关于自由存储区与堆区得到以下结论:

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

但至于前面说‘new/delete所申请销毁的区域也在堆上’这句话也不能算错。

malloc函数从上动态分配内存,也就是说函数返回的指针是指向堆里面的一块内存。操作系统中有一个记录空闲内存地址的链表。当操作系统收到程序的申请时,就会遍历该链表,然后就寻找第一个空间大于所申请空间的堆结点,然后就将该结点从空闲结点链表中删除,并将该结点的空间分配给程序。

new操作符从自由存储区(free store)上为对象动态分配内存空间,自由存储区是C++基于new操作符的一个抽象概念,凡是通过new操作符进行内存申请,该内存即为自由存储区。而堆是操作系统中的术语,是操作系统所维护的一块特殊内存,用于程序的内存动态分配,C语言使用malloc从堆上分配内存,使用free释放已分配的对应内存。自由存储区不等于堆,堆是一个实际的区域,而自由存储区是一个更上层的概念。通常new确实是在堆上申请内存,但是程序员可以自己重载new操作符,使用其他内存来实现自由存储(这并不常见)。另外,c++ primer plus这本书上有提到布局new,可以为对象在栈上分配内存。总的来说,自由存储区是new申请的区间的概念。如上所述,布局new就可以不位于堆中。

总结:

关于C/C++的内存分区前面两种分类方式都不能算错,造成分类的差异只是因为C语言和C++语言发展和语言背景的差异罢了,而现在大多数人都喜欢用‘C/C++’来统称这两门语言,而所谓的‘C/C++’其实更多指的是C++(C++在语言的设计上,将C作为子集,基本保留了C语言的语法和特性)所以才产生了种种分内的差异。

参考文章

https://www.cnblogs.com/QG-whz/p/5060894.html  

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值