`
yuanjinxiu
  • 浏览: 653467 次
文章分类
社区版块
存档分类
最新评论

LCC编译器的源程序分析(68)内存分配链表

 
阅读更多
LCC采用大块内存的方法,那它分配内存也是比较特殊的,它的源程序如下:
#001//大块内存结构。
#002struct block
#003{
#004 struct block *next; //后继块指针。
#005 char *limit; //尾位置
#006 char *avail; //可用的开始位置.
#007};
#008
#009//共用最大的类型.
#010union align
#011{
#012 long l;
#013 char *p;
#014 double d;
#015 int (*f)(void);
#016};
#017
#018//
#019union header
#020{
#021 struct block b;
#022 union align a;
#023};
#024
#025#ifdef PURIFY
#026union header *arena[3];
#027
#028void *allocate(unsigned long n, unsigned a) {
#029 union header *new = malloc(sizeof *new + n);
#030
#031 assert(a < NELEMS(arena));
#032 if (new == NULL) {
#033 error("insufficient memory/n");
#034 exit(1);
#035 }
#036 new->b.next = (void *)arena[a];
#037 arena[a] = new;
#038 return new + 1;
#039}
#040
#041void deallocate(unsigned a) {
#042 union header *p, *q;
#043
#044 assert(a < NELEMS(arena));
#045 for (p = arena[a]; p; p = q) {
#046 q = (void *)p->b.next;
#047 free(p);
#048 }
#049 arena[a] = NULL;
#050}
#051
#052void *newarray(unsigned long m, unsigned long n, unsigned a) {
#053 return allocate(m*n, a);
#054}
#055#else
#056
#057//三大块内存开始头.
#058static struct block first[] = {
#059 { NULL },{ NULL },{ NULL }
#060};
#061
#062//三大块内存的尾指针.
#063static struct block*arena[] = { &first[0], &first[1], &first[2] };
#064
#065//空闲块的内存头指针.
#066static struct block *freeblocks;
#067
#068//分配n个字节在a区域里.
#069void *allocate(unsigned long n, unsigned a)
#070{
#071 struct block *ap;
#072
#073 assert(a < NELEMS(arena));
#074 assert(n > 0);
#075
#076 //获取尾块指针。
#077 ap = arena[a];
#078
#079 //分配需要使用的内存和内存头。
#080 n = roundup(n, sizeof (union align));
#081
#082 //空闲内存是否大于需要分配的。
#083 while (n > (unsigned long)(ap->limit - ap->avail))
#084 {
#085 //如果有空闲块在列表里。
#086 if ((ap->next = freeblocks) != NULL)
#087 {
#088 //取得已经分配过的大块空闲内存。
#089 freeblocks = freeblocks->next;
#090 ap = ap->next;
#091 }
#092 else
#093 {
#094 //没有大块内存,开始分配大块内存。
#095 unsigned m = sizeof (union header) + n + roundup(10*1024, sizeof (union align));
#096
#097 //内存真实开始地址.
#098 ap->next = (block*)malloc(m);
#099
#100 //指向尾指针.
#101 ap = ap->next;
#102
#103 //分配内存是否出错.
#104 if (ap == NULL)
#105 {
#106 error("insufficient memory/n");
#107 exit(1);
#108 }
#109
#110 //内存块尾地址.
#111 ap->limit = (char *)ap + m;
#112 }
#113
#114 //实际上可以使用内存开始位置.
#115 ap->avail = (char *)((union header *)ap + 1);
#116
#117 //下一块内存为空.
#118 ap->next = NULL;
#119 arena[a] = ap;
#120 }
#121
#122 //移动大块内存的空闲开始位置,n是需要分配的内存.
#123 ap->avail += n;
#124
#125 //返回分配的内存地址开始位置.
#126 return ap->avail - n;
#127}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics