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

来源:互联网 发布:linux安装声卡驱动 编辑:程序博客网 时间:2024/05/23 21:55
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 }
 
 

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1759392


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 工作中总是马虎怎么办 孩子总是计算错误怎么办 做设计老是犯错怎么办 小学生阅读总出错怎么办 写作文没思路怎么办 孩子不爱写作文怎么办 写作文没有素材怎么办 写作文没有灵感怎么办 做事工作马虎粗心大意怎么办 小孩作业马虎粗心大意怎么办 孩子写字一直错怎么办 孩子写字老错怎么办 写错字涂黑了怎么办 写错字不能涂改怎么办 孩子爱写错别字怎么办 孩子读题马虎怎么办 孩子知错不该怎么办 小孩胆小反应慢怎么办 孩孑经常流鼻血怎么办 中考考号写错了怎么办 头后仰就头晕怎么办 感觉自己要晕倒怎么办 孩子不愿动手写字怎么办 老年人恶心想吐怎么办 小学生老写错别字怎么办 突然头晕站不稳 怎么办 早上起床突然天旋地转怎么办 躺着突然感觉天旋地转怎么办 眩晕症发作时怎么办 低血糖恶心想吐怎么办 更年期头晕头胀怎么办 年轻人头晕头胀怎么办 教案:《眯眼了怎么办》 迷路了怎么办活动意图 幼儿迷路了怎么办图片 中班迷路了怎么办教案 大门与大门相对怎么办 孩子长倒睫毛怎么办 孩子考倒数第一怎么办 孩子在班里倒数怎么办 宝宝不用吸管杯怎么办