LCC编译器的源程序分析(68)内存分配链表
2008-04-08 23:46
330 查看
LCC采用大块内存的方法,那它分配内存也是比较特殊的,它的源程序如下:#001 //大块内存结构。#002 struct block#003 {#004 struct block *next; //后继块指针。#005 char *limit; //尾位置#006 char *avail; //可用的开始位置.#007 };#008 #009 //共用最大的类型.#010 union align #011 {#012 long l;#013 char *p;#014 double d;#015 int (*f)(void);#016 };#017 #018 //#019 union header #020 {#021 struct block b;#022 union align a;#023 };#024 #025 #ifdef PURIFY#026 union header *arena[3];#027 #028 void *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 #041 void 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 #052 void *newarray(unsigned long m, unsigned long n, unsigned a) {#053 return allocate(m*n, a);#054 }#055 #else#056 #057 //三大块内存开始头.#058 static struct block first[] = { #059 { NULL }, { NULL }, { NULL } #060 };#061 #062 //三大块内存的尾指针.#063 static struct block *arena[] = { &first[0], &first[1], &first[2] };#064 #065 //空闲块的内存头指针.#066 static struct block *freeblocks;#067 #068 //分配n个字节在a区域里.#069 void *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 }
相关文章推荐
- LCC编译器的源程序分析(68)内存分配链表
- LCC编译器的源程序分析(68)内存分配链表
- LCC编译器的源程序分析(68)内存分配链表
- LCC编译器的源程序分析(68)内存分配链表
- LCC编译器的源程序分析(68)内存分配链表
- LCC编译器的源程序分析(68)内存分配链表
- LCC编译器的源程序分析(68)内存分配链表
- LCC编译器的源程序分析(68)内存分配链表
- LCC编译器的源程序分析(68)内存分配链表
- LCC编译器的源程序分析(68)内存分配链表
- LCC编译器的源程序分析(68)内存分配链表
- LCC编译器的源程序分析(68)内存分配链表
- LCC编译器的源程序分析(68)内存分配链表
- LCC编译器的源程序分析(68)内存分配链表
- LCC编译器的源程序分析(68)内存分配链表
- LCC编译器的源程序分析(67)删除内存链表
- LCC编译器的源程序分析(67)删除内存链表
- LCC编译器的源程序分析(67)删除内存链表
- LCC编译器的源程序分析(67)删除内存链表
- LCC编译器的源程序分析(67)删除内存链表