fedorayang 发表于 2016-05-19 17:35

丹尼斯.里奇的c语言教程malloc例子两个疑问

/**
QUESTION1: bp < p->s.ptr 什么时候出现,插入到哪里?
ANSWER1:

QUESTION2: join to lower, freep好像指向的位置比其他情况不一样,这会导致什么问题,会导致morecore多一次调用吗.
ANSWER2: 会导致循环开始位置不一样,不会导致morecore多一次调用,假如只能使用这次释放的内存块的话,
               会循环过去,指到freep位置时,大小满足了,就拿到数据返回.
               
QUESTION3: &base地址在ubuntu64bit上测试确实比sbrk获得的地址低,这依靠了系统相关特性,假如在相反的平台上程序是否可以正常运行.       
ANSWER3:                
*/
#include <stdio.h>

typedef long Align; /* for alignment to long boundary */
union header { /* block header */
        struct {
                union header *ptr; /* next block if on free list */
                unsigned size; /* size of this block */
        } s;
        Align x; /* force alignment of blocks */
};
typedef union header Header;

static Header base; /* empty list to get started */
static Header *freep = NULL; /* start of free list */

/* free: put block ap(AccessPoint) in free list */
void free(void *ap)
{
        Header *bp, *p;
        bp = (Header *)ap - 1; /* point to block header */
        for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr)
        {               
                if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) /* QUESTION1 */
                {
                        break; /* freed block at start or end of arena */
                }       
        }
               
        if (bp + bp->s.size == p->s.ptr) { /* join to upper(next) nbr */
                bp->s.size += p->s.ptr->s.size;
                bp->s.ptr = p->s.ptr->s.ptr;
        }
        else
                bp->s.ptr = p->s.ptr;
       
        if (p + p->s.size == bp) { /* join to lower(prev) nbr */
                p->s.size += bp->s.size;/* QUESTION2 */
                p->s.ptr = bp->s.ptr;
        }
        else
                p->s.ptr = bp;
       
        freep = p;
}

#define NALLOC 1024 /* minimum #units to request */
/* 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 */
                return NULL;
        up = (Header *)cp;
        up->s.size = nu;
        free((void *)(up + 1));
        return freep;
}

/* malloc: general-purpose storage allocator */
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 = freep = prevp = &base; /* QUESTION3 */
                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 */
        }
}


int main(int argc, char* argv[])
{
        char* p0=NULL;
        char* p1=NULL;
        char* p2=NULL;
        char* p3=NULL;
        char* p4=NULL;       
               
        p0=malloc(4096);
        if(NULL!=p0)
        {               
                free(p0);       
        }
       
        p1=malloc(1024);
        p2=malloc(1024);
        p3=malloc(1024);
        p4=malloc(1024);       
       
        if(NULL!=p1)
        {               
                free(p1);               
        }
       
        if(NULL!=p2)
        {               
                free(p2);               
        }

        if(NULL!=p3)
        {               
                free(p3);       
        }

        if(NULL!=p4)
        {
                free(p4);       
        }       
        return 0;
}
页: [1]
查看完整版本: 丹尼斯.里奇的c语言教程malloc例子两个疑问