linux0.11中*((char **) cp)的分析

 Dear tony,

在linux 0.11 内核代码中,在malloc.c文件Line 160-163中有如下几行代码:

for (i=PAGE_SIZE/bdir->size; i > 1; i--) {
   *((char **) cp) = cp + bdir->size;
   cp += bdir->size;
  }

这段代码写的非常巧妙、非常难懂,经过同事JASON的一番指导,才搞明白。

首先,我在VC6.0中写了一段类似的代码:

#define PAGE_SIZE 4096
#define BDIR_SIZE 16


int main()
{
 char *cp;
 int i;

 (void *)cp = malloc(PAGE_SIZE);

 for(i = PAGE_SIZE/BDIR_SIZE; i > 1; i--)
 {
  *((char **)cp) = cp + BDIR_SIZE;  
  cp += BDIR_SIZE;
 }

 *((char **)cp) = 0;

 printf("The result./n");
 
 return 0;
}

这段代码的意思是:申请4KB的内存,并且cp指向这个内存的首地址。然后,把这个4KB的内存划分成许多块,每块的大小是16B,接着就进行了与linux 0.11内核中同样的操作:

*((char **)cp) = cp + BDIR_SIZE; 

这时,通过VC6.0调试可以得到,申请4KB的内存的首地址是:0x003751f0,

可以推算它的结尾地址是:0x003761ef。

运行程序后,打开调试的Memory窗口,查看0x003751f0 ~ 0x003761ef的内容:

addr            content

003751F0  00375200  CDCDCDCD 
003751F8  CDCDCDCD  CDCDCDCD 
00375200  00375210  CDCDCDCD 
00375208  CDCDCDCD  CDCDCDCD 
00375210  00375220  CDCDCDCD 
00375218  CDCDCDCD  CDCDCDCD 
00375220  00375230  CDCDCDCD

..........

发现没???

从首地址003751F0开始的16B的数据是00375200  CDCDCDCD CDCDCDCD  CDCDCDCD,

细心的观众可能发现了,前4B的数据就是首地址003751F0后16B的地址。

到现在,估计大家都明白了,

*((char **)cp) = cp + BDIR_SIZE; 就是把cp指向内存的内容设置成cp + BDIR_SIZE的地址。

这样做的好处是让一个桶中的内存块都link起来。

OVER。。。。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值