XI`AN TECHNOLOGICAL UNIVERSITY 实验报告西安工业大学实验报告一、实验目的1.加深对可变分区的存储管理的理解。
2.熟悉主存分配与回收。
3.理解在不同存储管理方式,如何实现贮存空间的分配与回收。
4.掌握动态分区分配中的方式中的数据结构和分配算法及动态分区存储管理方式及其实现过程。
二、实验原理实现方式:C语言单链表。
建立两个链表,空闲表和已分配表,分别将未分配的作业和已分配好的作业放入其中。
当要装入一个作业时,从空闲区表中查找空闲区,从中找出一个能容纳该作业的空闲区。
如果找到的空闲区正好等于该作业的长度,则把该分区全部分配给作业,这时应该把该空闲分区从链表上删除。
同时在已分配区表中插入这个已申请的结点。
如果找到的空闲区大于作业长度,则把空闲区分成两部分,一部分用来装入作业,另外一部分仍为空闲区。
实验采用的有“最优适应”算法。
最优适应算法是按作业要求挑选一个能满足作业要求的最小空闲区,这样保证可以不去分割一个大的区域,使装入大作业时比较容易得到满足。
“最坏适应算法”,他是根据分配空间的大小分配空间,空闲区按照从大到小的顺序,排好序,这样子每次都分配最大的分区,会让空闲分区的碎片不会很多。
“首次适应算法”,按地址从小到大排序。
“循环首次适应算法”地址还是按照从小到大排序的,但是查找会从上一次查找的地方开始继续查找。
四、实验步骤、数据记录及处理实验步骤:1.首先是链表的建立,它分为了这样子的一个结构体,typedef struct _MEN{int data;int head; //起始地址int tail; //结束地址struct _MEN *next;}MEN;2.考虑申请释放和回收,申请的时候:你必须先看到知道进程的大小的进程名,从空闲区表中查找空闲区,从中找出一个能容纳该作业的空闲区。
如果找到的空闲区正好等于该作业的长度,则把该分区全部分配给作业,这时应该把该空闲分区从链表上删除。
同时在已分配区表中插入这个已申请的结点。
如果找到的空闲区大于作业长度,则把空闲区分成两部分,一部分用来装入作业,另外一部分仍为空闲区。
回收的时候:如果在这个大小和进程名,会被考虑他的大小跟他的上下有没有必要链接起来。
这个是在找有没有跟上面的链接的p1 ->head == s->tail (s为需要释放的结点)while(p1 !=NULL){if(p1 ->head == s->tail){flag1 = false;p1->data = s->data + p1->data;p1->head = s->head;free(s);break;}p1= p1->next;}跟下面的比较看看是否相邻p1->tail == s->head(s为需要释放的结点)。
p1 = p->next;while(p1 != NULL){if(p1->tail == s->head){flag2 = false;p1->data = s->data +p1->data;p1->tail = s->head;}p1= p1->next;}3.四个算法的实现:以循环首次适应算法为例,这个为了达到从上次查询的地方寻找,我在这里运用了一个static变量。
先从上次找到的地方继续寻找,如果没找到,那就是从头开始找到那个上次寻找的地方,如果还是没找到,那么就灰显示,这个大小太大不符合。
实验代码(四个算法为例c):void ff(char name,MEN *p,MEN *ap,int num ) // 首次适应算法{MEN *s = p->next; // 空闲链表MEN *q = ap->next; //申请的链表集MEN *tmp = alloc(num);while(s!= NULL){if(s->data > num){tmp->head = s->head;tmp->tail = tmp->head + num;//s->name = name;s->data = s->data -num;s->head = s->head + num;s->tail = s->tail;break;}else if(s->data == num){tmp->head = s->head;tmp->tail = s->tail;// s->name = name;q->next = s->next;break;}q = s;s = s->next;}while(ap->next != NULL){ap = ap->next;}ap->next =tmp;tmp->name = name;}void nf(char name,MEN *p,MEN *ap,int num ) // 循环首次适应算法{static MEN *st = p->next;MEN *s = st; // 空闲链表MEN *q = ap->next; //申请的链表集MEN *tmp = alloc(num);bool flag = true;while(s!= NULL){if(s->data > num){tmp->head = s->head;tmp->tail = tmp->head + num;s->data = s->data -num;s->head = s->head + num;s->tail = s->tail;st = s;flag = false;break;}else if(s->data == num){tmp->head = s->head;tmp->tail = s->tail;q->next = s->next;st = s;flag = false;break ;//free(s);}q = s;s = s->next;}if(flag){for(MEN *p1 = p->next;p1 != st ;p1 = p1->next) //在当前指针所指的方向,一下没找到,就在开始招{if(p1->data > num){tmp->head = p1->head;tmp->tail = tmp->head + num;p1->data = p1->data -num;p1->head = p1->head + num;p1->tail = p1->tail;st = p1;flag = false;break;}else if(p1->data == num){tmp->head = p1->head;tmp->tail = p1->tail;q->next = p1->next;st = p1;flag = false;break ;//free(s);}}}while(ap->next != NULL){ap = ap->next;}ap->next =tmp;tmp->name = name;}void bf(char name,MEN *p,MEN *ap,int num ) // 最佳适应算法{sort_size(p);MEN *s = p->next; // 空闲链表MEN *q = ap->next; //申请的链表集MEN *tmp = alloc(num);while(s!= NULL){if(s->data > num){tmp->head = s->head;tmp->tail = tmp->head + num;s->data = s->data -num;s->head = s->head + num;s->tail = s->tail;break;//continue;}else if(s->data == num){tmp->head = s->head;tmp->tail = s->tail;q->next = s->next;break;//free(s);}q = s;s = s->next;}while(ap->next != NULL){ap = ap->next;}ap->next =tmp;tmp->name = name;}void wf(char name,MEN *p,MEN *ap,int num ) // 最坏适应算法{sort_size_a(p);MEN *s = p->next; // 空闲链表MEN *q = ap->next; //申请的链表集MEN *tmp = alloc(num);while(s!= NULL){if(s->data > num){tmp->head = s->head;tmp->tail = tmp->head + num;s->data = s->data -num;s->head = s->head + num;s->tail = s->tail;break;//continue;}else if(s->data == num){tmp->head = s->head;tmp->tail = s->tail;q->next = s->next;break;//free(s);}q = s;s = s->next;}while(ap->next != NULL){ap = ap->next;}ap->next =tmp;tmp->name;}4.实验截图:测试数据:a申请300,b申请100,释放a,c申请50。
循环首次适应算法:最坏适应算法:11。