大牛们是这样解释程序的存储空间和内存分配的

一直堆进程的存储区分配和堆栈认识比较模糊,今天看了下<<UNIX环境高级编程>>,<<K&R>> ,还有<<C标准库>>有关这方面的解释.综合综合这三本书的解释,对C程序的内存分配才有了更清楚的认识. 

<<C标准库>>的解释

一个标准C程序的数据对象占据一下三种类型的存储空间:

①: 程序开始执行前分配静态存储空间并进行初始化.如果没有指定一个数据对象(部分或者全部)的初始值,程序就会把它的每一个标量部分初始化未零.这样的数据对象一直存在,知道程序结束.

②:程序在每一个块的入口分配动态存储空间.如果没有指定一个数据对象的初始值,那么它的初始内容是不确定的.这样的数据对象存在到块的执行终止.


③:只有当调用函数calloc ,malloc ,或者realloc 时,程序才分配可控制的(allocated)存储空间 .只有调用calloc时,它才会把这样的一个数据对象初始化未一个零字符的数组.这样的数据对象一直存在到用它的地址作为参数调用free函数,或者知道程序结束.


堆 

静态存储空间存在于程序的整个执行过程当中.动态存储空间遵循后进先出的原则,它可以用一个栈实现.动态存储空间经常与函数调用和返回信息共享调用栈.可控的存储空间不遵循这样的原则.程序可以按照任意顺序对这样的数据对象混合进行分配和释放.因此,C标准库必须维持一个独立的称作对的空间来满足控制存储空间的要求.[对准的解释准确到位,其它大多数的书本讲到堆时都会给你将一大堆堆的特性,可是讲了半天也没讲明白对倒低是个什么东西]


在一些实现中,调用栈和堆要竞争有限的存储空间.使用malloc分配猪狗的空间就额能限制以后调用函数的深度,或者可能会很容易用完堆中的空间.在任何情况下,都应该只分配需要的空间,并在用完之后尽快释放它.


堆的开销:

可控的存储空间必然会涉及开销的问题.每一个分配的数据对象都要由足够多的信息让free 来确定将要释放的区域的大小,分配1000个单字符的数据可能很容易消耗4到8倍的存储空间.堆也容易受到碎片的影响.子啊对上按照任意顺序分配和释放数据对象会不可避免的在某些分配的数据对象之间留出一些不可使用的小空间.这样就大大减小了堆的可用大小.

把相关的数据构建到一个结构块中,并一次分配所有的空间,这样会使堆的开销减小到最小,而且这也是一种好的编程风格.但不要为了节省堆开销而把不相关的数据聚集到一起.为那些具有相近生存周期的数据对象分配空间,然后几乎同时释放他们,这样就会使堆的破碎成都最小化.不要为了减小堆的破碎成都而提前或者推迟不相关的堆操作.存储分配函数对编程的灵活性有很大的帮助,要按照他们期望的方式去使用他们.



存储分配:

malloc 并不是从一个在编译时就确定的固定大小的数组中分配存储空间,而是在需要时向操作系统申请空间.因为程序中的某些地方可能不通过,malloc调用申请空间(也就是说通过其它方式申请空间),所以malloc故那里的空间不一定是连续的.空闲存储空间以空闲块链表的方式组织,每个块包含一个长度,一个指向西一块指针以及一个指向自身存储空间的指针.这些块按照存储地址的升序组织,最后一块(最高地址)指向第一块


当有申请时,malloc将扫描空闲链表块,直到有一个够大的块为止.算法称为 首次适应(first fit);与此相对应的算法是最佳适应(best fit),它寻找满足条件的最小块.


释放的过程也是首先收索空闲链表块,找到可以插入释放块的适合位置,如果与释放块的任一边是一个空闲块,则将两个块合成一个更大的块.这样存储空间就不会有太多的碎片.因为空闲块链表是以地址的顺序递增链接在一起的,所以很容易判断相邻的块是否空闲.


UNIX系统调用中处理存储器分配的是sbrk ,它不是一个通用的存储管理器.它按指定字节增加或减少进程的地址空间.如何管理该地址空间却取决于进程. 存储分配函数malloc实现一种特定类型的分配.如果我们不喜欢起操作方式,可以定义自己的malloc函数,他很可能将使用sbrk系统调用.图1-2 显示了应用程序,malloc函数,以及sbrk系统调用之间的关系.


内核中的系统调用分配另外一块空间给进程,而库函数malloc则在用户层次管理这一空间.sbrk可以扩充或者缩小进程的空间,但是大多数malloc 和free的实现都不减小进程的存储空间,释放的空间被保存在malloc池中,而不返回给内核.释放的空间可以供以后再分配.  


1. 想了解更详细的内容可以参考:  
2.    <<UNIX环境高级编程>>  (188页 7.8 存储器分配  )  
3.    <<C标准库>>   (342页 13.3 存储分配函数 )  
4.    <<the C programming>> (152页  8.7 存储分配程序)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值