c语言 - 对 malloc 的 K&R 实现感到困惑

  • 本文关键字:实现 语言 malloc c malloc
  • 更新时间 :
  • 英文 :


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 = 5,nunits = 2。根据代码,我们首先从 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;

我错过了什么吗?

答案就在这一行

nunits = (nbytes+sizeof(Header)-1)/sizeof(header) + 1;

该行取nbytes请求的字节数,将sizeof(Header)-1相加以四舍五入,除以sizeof(header)得到容纳nbytes所需的单位数。最后,它添加 1 为标头腾出空间。因此,之后的所有代码都假设您为nbytes保留空间(如果需要,还可以添加填充)和标头。

相关内容

  • 没有找到相关文章

最新更新