1
为函数malloc()的代码的低于困惑K&R执行以K & R段8.7的malloc
void *malloc(unsigned nbytes) {
Header *p, *prevp;
Header *moreroce(unsigned);
unsigned nunits;
nunits = (nbytes+sizeof(Header)-1)/sizeof(header) + 1;
if ((prevp = freep) == NULL) { /* no free list yet */
base.s.ptr = freeptr = prevptr = &base;
base.s.size = 0;
}
for (p = prevp->s.ptr; ; prevp = p, p = p->s.ptr) {
if (p->s.size >= nunits) { /* big enough */
if (p->s.size == nunits) { /* exactly */
prevp->s.ptr = p->s.ptr;
} else { /* allocate tail end */
p->s.size -= nunits;
p += p->s.size;
p->s.size = nunits;
}
freep = prevp;
return (void *)(p+1);
}
if (p == freep) /* wrapped around free list */
if ((p = morecore(nunits)) == NULL)
return NULL; /* none left */
}
}
我主要是由“分配尾端”部分相混淆。根据代码,我们首先从p-> s.size中减去2,将p前进3,在该地址记录分配的大小,并返回(void *)(p + 1)。
设p'表示自增后的p,*表示自由空间。上述操作后,内存应该是这样的:
P * * P” *
实际上我们分配了2个单位的内存,但对于p剩余的可用空间应该是2,而不是3,因为一个单元被分配的尾端的头部信息占用。
所以我觉得行
p->s.size -= nunits;
应
p->s.size -= nunits + 1;
代替我错过了什么?
谢谢您的澄清!我混淆了这两个变量。但如果是这样,不应该p自增加p-> s.size + 1而是为了得到正确的头部位置? – Loopz
这由返回'p + 1'的'return'语句处理。基本上,代码基于块的概念,其中包括标题,数据和填充。它在开始时调整请求大小,并在末尾调整指针。两者之间的所有内容都使用块指针。 – user3386109
仍然假设p-> s.size = 5。我们有从0到5索引的内存地址。p最初是0,它有1到5的空闲内存。如果nbytes = 2,我认为p应该前进到4并且返回5.但似乎p提前到3,而返回4。 – Loopz