C语言内存的动态存储管理4-边界标识法

就空闲链表来说,要确定哪些空闲块是物理地址相邻的,确实不太容易,需要整表扫描。

边界标识法能够有效的判断空闲块的物理相邻内存块是否为空闲块。

所有的空闲块组成一个双向循环链表,链表中每一个节点的结构如下:

llinkrlink分别指向链表中的前驱后继节点。

size表明内存块的大小。

uplink指向本块的首地址,图中箭头,其作用下面讲述。

tag头和尾中各有一个,作为内存块边界的标识,0表空闲块,1表占用块。

分配时同样会在链表上产生很多非常小的空闲块,影响分配的效率,因此,可以定义一个全局的指针p,当不为空时分配,使其始终指向刚进行过分配的节点的后继节点。

回收时判断物理相邻的块是否为空闲块的方法:

假设当前回收块的物理地址为p(下面涉及到的左邻块和右邻块都是物理地址相邻的,在循环链表中也许不相邻),

左邻块:左邻块的尾的地址是p1=p-sizeof(尾),左邻块是否为空闲块的判断则为p1->tag是否为0。当为空闲块时,只需将当前块合并到左邻块中即可,而左邻块的地址则需要由uplink来获得(原因是中间内存块的大小是不固定的,不能通过偏移来实现),即p1->uplink。修改左邻块的size和uplink即可。

右邻块:右邻块的首的地址为p2=p+sizeof(头),右邻块是否为空闲块的判断则为p2->tag是否为0。当为空闲块时,与右邻块合并,修改p的llink、rlink和size,修改p2的uplink。

 

你可能会认为,既然链表中的块都是空闲块,干吗还要加上tag标识位呢?我的回答是,如果没有tag,当我们找到右邻块的地址时,没有办法判断右邻块是不是链表中的一个节点,也许它还在被用户使用着。那为什么要用两个tag呢?个人觉得,用一个也可以,但用两个更容易判断。

 

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值