现在的位置: 首页 > 综合 > 正文

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

2018年02月19日 ⁄ 综合 ⁄ 共 1088字 ⁄ 字号 评论关闭

 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。。。。

 

抱歉!评论已关闭.