lcc源代码解析之alloc.c

本章学习lcc的内存管理模块,同string处理模块类似,这个模块也可以独立于lcc使用,

实际上这个模块实现的是一个简单的内存池的概念,具体代码如下:

#include "c.h"
/*lcc内存管理的基本单位,以链表组成的block形式存在*/
struct block {
	struct block *next;
	char *limit;/*从block的起始地址到limit的这段空间表示这个block的总大小*/
	char *avail;/*从起始地址到avail是已经分配区域,从avail到limit是可继续分配空间*/
};
union align {
	long l;
	char *p;
	double d;
	int (*f)(void);
};
union header {
	struct block b;
	union align a;
};
#ifdef PURIFY/*主要用于内存问题的debug*/
union header *arena[3];

void *allocate(unsigned long n, unsigned a) {
	union header *new = malloc(sizeof *new + n);

	assert(a < NELEMS(arena));
	if (new == NULL) {
		error("insufficient memory\n");
		exit(1);
	}
	new->b.next = (void *)arena[a];
	arena[a] = new;
	return new + 1;
}

void deallocate(unsigned a) {
	union header *p, *q;

	assert(a < NELEMS(arena));
	for (p = arena[a]; p; p = q) {
		q = (void *)p->b.next;
		free(p);
	}
	arena[a] = NULL;
}

void *newarray(unsigned long m, unsigned long n, unsigned a) {
	return allocate(m*n, a);
}
#else
static struct block
	 first[] = {  { NULL },  { NULL },  { NULL } },
	*arena[] = { &first[0], &first[1], &first[2] };
static struct block *freeblocks;/*指向空闲链表的指针*/

void *allocate(unsigned long n, unsigned a) {
	struct block *ap;

	assert(a < NELEMS(arena));
	assert(n > 0);
	ap = arena[a];

	//字节对齐
	n = roundup(n, sizeof (union align));//sizeof (union align) = 8
	while (n > ap->limit - ap->avail) {
		if ((ap->next = freeblocks) != NULL) {/*是否有空闲内存*/
			freeblocks = freeblocks->next;
			ap = ap->next;
		} else//malloc new
			{
				unsigned m = sizeof (union header) + n + roundup(10*1024, sizeof (union align));
				ap->next = malloc(m);
				ap = ap->next;
				if (ap == NULL) {
					error("insufficient memory\n");
					exit(1);
				}
				ap->limit = (char *)ap + m;
			}
		ap->avail = (char *)((union header *)ap + 1);
		ap->next = NULL;
		arena[a] = ap;

	}
	ap->avail += n;
	return ap->avail - n;/*返回原来的avail*/
}

void *newarray(unsigned long m, unsigned long n, unsigned a) {
	return allocate(m*n, a);
}
void deallocate(unsigned a) {
	assert(a < NELEMS(arena));
	arena[a]->next = freeblocks;//并未真正free,而是加入空闲链表
	freeblocks = first[a].next;
	first[a].next = NULL;
	arena[a] = &first[a];
}
#endif


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值