1. 可利用空间表及分配方法
两种结构的可利用空间表: 目录表和链表
此仅讨论链表.
常用的三种分配策略:
1. 首次拟合法: 从表头指针开始查找可利用空间表, 将找到的第一个大小不小于 n 的空闲块的一部分分配给用户.
2. 最佳拟合法: 将可利用空间表中一个不小于 n 且最接近 n 的空闲块的一部分分配给用户.
3. 最差拟合法: 将可利用空间表中不小于 n 且是链表中最大的空闲块的一部分分配给用户.
边界标识法: 在每个内存区的头部和底部两个边界上分别设有标识, 以标识该区域为占用块还是空闲块.
可利用空间表结点定义如下:
- typedef struct Word{
- union{
- Word *llink;
- Word *uplink;
- }
- int tag;
- int size;
- Word *rlink;
- OtherType other;
- }Word,head,foot,*Space;
分配算法:
- #define FootLoc(p) (p+p->size-1)
- Space AllocBoundTag(Space &pav,int n){
- for(p=pav;p && p->size <n && p->rlink !=pav;p=p->rlink);
- if(!p || p->size <n) return NULL;
- else{
- f=FootLoc(p);
- pav=p->rlink;
- if(p->size - n <= e){
- if(pav == p) pav =NULL;
- else{
- pav->llink=p->llink;
- p->llink->rlinl=pav;
- }
- p->tag=f->tag=1;
- }else{
- f->tag=1;
- p->size -=n;
- f=FootLoc(p);
- f->tag=0;
- f->uplink=p;
- p=f+1;
- p->tag=1;
- p->size=n;
- }
- return p;
- }
- }
回收算法:
由于在每个内存区的边界上都设有标志值, 因此很容易识别释放内存区的物理地址比邻的内存区是否是占用块还是空闲块.
因此释放内存区的左右邻区有四种情况:
1. 释放块的左右邻区都为占用块
- p->tag=0;
- FootLoc(p)->uplinl=p;
- FootLoc(p)->tag=0;
- if(!pav) pav=p->llink=p->rlink=p;
- else{
- q=pav->llink;
- p->rlink=pav;
- p->llink=q;
- q->rlink=pav->llink=p;
- pav=p;
- }
2. 释放块的左邻区为空闲块, 右邻区为占用块
- n=p->size;
- s=(p-1)->uplink;
- s->size +=n;
- f=p+n-1;
- f->uplink=s;
- f->tag=0;
3. 释放块的右邻区为空闲块, 左邻区为占用块
- t=p+p->size;
- p->tag=0;
- q=t->llink;
- p->llink=q;
- q->rlink=p;
- q1=t->rlink;
- p->rlink=q1;
- q1->llink=p;
- p->size +=t->size;
- FootLoc(t)->uplink=p;
4. 释放块的左右邻区都为空闲块
- n=p->size;
- s=(p-1)->uplink;
- t=p+p->size;
- s->size +=n+t->size;
- q=t->llink;
- q1=t->rlink;
- q->rlink=q1;
- q1->llink=q;
- FootLoc(t)->uplink=s;
来源: http://www.bubuko.com/infodetail-3003587.html