Created
April 24, 2017 10:49
-
-
Save WyattJia/faf15f5a7570dafae8631acce1722019 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define NALLOC 1024 /* minimum #units to request */ | |
typedef long Align; /* for alignment to long boundarg. 假定 long 类型为最受限的类型。*/ | |
/* 空闲块包含的内容: | |
* 一个指向链表中下一个块的指针 | |
* 一个块大小的记录 | |
* 一个指向空闲空间本身的指针 | |
*/ | |
/* 该联合中, Align 字段永远也不会被使用,仅仅用于强制每个头部在最坏的情况下满足对其要求 */ | |
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 */ | |
/* 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 = 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 个单元, | |
* 这个较大的块将根据需求分解成较小的块。 */ | |
return NULL; /* 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 */ | |
return NULL; | |
up = (Header *) cp; | |
up->s.size = nu; | |
free((void *)(up+1)); | |
return freep; | |
} | |
/* free: put block ap in free list */ | |
void free(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 */ | |
if (bp + bp->size == p->s.ptr) { /* join to upper 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->size == bp) { /* join to lower nbr */ | |
p->s.size += bp->s.size; | |
p->s.ptr = bp->s.ptr; | |
} else | |
p->s.ptr = bp; | |
freep = p; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment