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 ) /* morecore 用于向操作系统请求存储空间。 * 我们不希望每次调用 malloc 函数时执行该操作, * 所有 morecore 函数请求至少 NALLOC 个单元, * 这个较大的块将根据需求分解成较小的块。 */ returnNULL; /* none left */ } }
/* morecore: ask system for more memory */ static Header *morecore(unsigned nu) { char *cp, *sbrk(int); Header *up; if (nu < NALLOC) nu = NALLOC; cp = sbrk(nu * sizeof(Header)); if (cp == (char *) -1) /* no space at all */ returnNULL; up = (Header *) cp; up->s.size = nu; free((void *)(up+1)); return freep; }
/* free: put block ap in free list */ voidfree(void *ap) { Header *bp, *p;
bp = (Header *)ap - 1; /* point to block header */ for (p = freep; !(bp > && bp < p->s.ptr); p = p->s.ptr) if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) break; /* fread block at start or end of arena */