Explanation on K&R 8.7 A Storage Allocator

Anyone has a basic knowledge of C can use malloc(), but under the cover what really happens? Well, K&R give us a simple version of a storage allocator. Simple as it is, it is still very hard for the beginners to understand. The free() function is especially confusing, what’s on earth the author’s talking about? OK, fellow me.

 1  /*  free:  put block ap in free list  */
 2      void  free( void   * ap)
 3     {
 4         Header  * bp,  * p;
 5 
 6         bp  =  (Header  * )ap  -   1 ;     /*  point to  block header  */
 7          for  (p  =  freep;  ! (bp  >  p  &&  bp  <  p -> s.ptr); p  =  p -> s.ptr)
 8               if  (p  >=  p -> s.ptr  &&  (bp  >  p  ||  bp  <  p -> s.ptr))
 9                   break ;   /*  freed block at start or end of arena  */
10 
11          if  (bp  +  bp -> size  ==  p -> s.ptr) {     /*  join to upper nbr  */
12             bp -> s.size  +=  p -> s.ptr -> s.size;
13             bp -> s.ptr  =  p -> s.ptr -> s.ptr;
14         }  else
15             bp -> s.ptr  =  p -> s.ptr;
16          if  (p  +  p -> size  ==  bp) {             /*  join to lower nbr  */
17             p -> s.size  +=  bp -> s.size;
18             p -> s.ptr  =  bp -> s.ptr;  // unnecessary maybe?
19         }  else
20             p -> s.ptr  =  bp;
21         freep  =  p;
22     }

 

First, we have bp point to the header of the block we want to put in the free list. Then, we have a working pointer initialized to freep. Because the free list is a singly circularly linked list, we can loop around to find a p where bp is between p and pnext(that is p->s.ptr) in the free list if we assume bp is already in the list(It is important to view the linked list as a circle). How can we describe this condition in C? bp, p and pnext all have a address in the physical memory(view them as linear this time). These addresses are comparable. Normally pnext is greater than p, then we can say p<bp<pnext, but what if p is the last block and pnext is the first block when view the free list as linear memory locations. In this case, p is certainly greater than pnext. Now view the list as circle again, in order to put bp between p and pnext, bp may appear after p or before pnext in the linear memory. Thus we get two more inequalities: pnext<p<bp or bp<pnext<p. Every case will fall into one of the three categories. That what’s the for loop does. When any one of the three inequalities are meet, the for loop will exit.

Now we have bp in the middle of p and pnext in the circularly linked list. The remaining works are keeping the pointers pointing to the right things and the sizes correct. If bp is adjacent to either neighbor, the adjacent blocks are combined. (IMPORTANT!! View the list as circle now, regardless of their physical position, their relative position in the circularyly linked list is fixed, with p be the first, and bp be the midlle one and pnext comes last) If bp is adjacent to pnext, then bp is combined with pnext, pnext vanishes, bp get a new size, bp->s.adr has to point to pnext->s.adr. if bp is not adjacent to pnext, then bp->s.adr has to point to pnext, because pnext comes after bp in the new list. Similarly, if bp is adjacent to p, bp vanishs, and pointers remain the same, p gets a new size. If not, bp->s.adr has to point to bp. Well, All finished.

In summary, the two kinds of view we use here is very important. View the list as linear when we compare the address. View the list as circular when fix the pointers. The observation which allow us to apply general operation on the list is also very important, that is to find a p where bp is between p and pnext(that is p->s.ptr), we can always find such a p, because bp must be anywhere in the memory.

转载于:https://www.cnblogs.com/sirkay777/archive/2009/03/04/1403374.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值