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