第四章

一、目的和要求

1. 实验目的

用高级语言完成一个主存空间的分配和回收程序,以加深对动态分区分配方式及其算法的理解。

2.实验要求

采用连续分配方式之动态分区分配存储管理,使用首次适应算法、循环首次适应算法、最佳适应算法和最坏适应算法4种算法完成设计(任选两种算法)。

(1)设计一个作业申请队列以及作业完成后的释放顺序,实现主存的分配和回收。采用分区说明表进行。

(2)或在程序运行过程,由用户指定申请与释放。

(3)设计一个空闲区说明表,以保存某时刻主存空间占用情况。把空闲区说明表的变化情况以及各作业的申请、释放情况显示。

二、实验内容

编写并调试一个模拟的内存分配与回收程序,使用首次适应算法、循环首次适应算法对内存空间的分配与回收。

三、实验方法、步骤及结果测试

1.    源程序名:a.cpp

可执行程序名:a.exe

2.    原理分析

(1)编写该程序首先要给定一个一定空间大小的内存,即申请空闲区空间最大值,并且要定义空间的各分区的作业标号、分区起始地址、分区长度,单位为字节、分区表的状态位、前向指针、后向指针、已分配分区表、空闲分区等。

(2)通过定义空间分区后,还要定义空间分区链表并对其进行初始化,对空闲分区和已分配分区进行链表访问,对于空闲分区可以分配给新进来的进程使用,对于已分配的分区,则等进程执行结束后在回收空间,恢复空闲区。通过链表的访问实现整个空间分区的分配与回收。

3.      主要程序段及其解释:

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include <conio.h>
  4 #define nil -1
  5 #define NULL 0
  6 #define maxisize 600    //用户的空闲区空间最大值
  7 #define minisize 4     
  8 #define getspace(type) (type*)malloc(sizeof(type)) //分配空间
  9 struct table{
 10     char job;                 //作业标号
 11     float address;            //分区起始地址
 12     float length;             //分区长度,单位为字节
 13     int flag;                 //分区表的状态位
 14     struct table *FRlink;     //前向指针
 15     struct table *RElink;    //后向指针
 16 }*free_table=NULL,*place;   //已分配分区表,空闲分区表
 17 typedef struct table FRtable;
 18 //空间分区链表初始化
 19 FRtable *init(FRtable *tb)
 20 {
 21     tb->FRlink=NULL;
 22     tb->job=nil;
 23     tb->address=1064;
 24     tb->length=1664;
 25     tb->flag=0;
 26     tb->RElink=NULL;
 27     return tb;
 28 }
 29 //主存分配函数,为作业job分配大小为xk的分区空间
 30 void allocate(char job,float xk,int choice)
 31 {
 32     FRtable *tb,*link;
 33     int k=0;
 34     float temp=600;
 35     if (free_table->FRlink==NULL&&free_table->RElink==NULL)
 36     {//给首个作业分配空间,改写分区链表
 37         free_table->job=job;
 38         free_table->length=xk;
 39         free_table->flag=1;
 40         if (xk<maxisize)
 41         {
 42             tb=getspace(FRtable);
 43             free_table->RElink=tb;
 44             tb->FRlink=free_table;
 45             tb->job=nil;
 46             tb->address=1064+xk;
 47             tb->length=maxisize-xk;
 48             tb->flag=0;
 49         }
 50         if (choice==2)
 51         {//链接成循环链表
 52             free_table->FRlink=tb;
 53             tb->RElink=free_table;
 54             place=tb;
 55         }
 56         else
 57         {
 58             free_table->FRlink=NULL;
 59             if (xk<maxisize) tb->RElink=NULL;
 60         }
 61         k=1;
 62     }
 63     else
 64     {
 65         if (2==choice) tb=place;//采用CFF时将ta定位到上次找到的合适空间分区的下个空间分区
 66         else tb=free_table;
 67         while(tb!=NULL)
 68         {
 69             if (3==choice)
 70             {
 71                 while(tb!=NULL)
 72                 {
 73                     if (tb->length>=xk&&tb->flag==0)
 74                         if (tb->length<temp)
 75                             {place=tb;temp=tb->length;}   //选择最适合空间
 76                     tb=tb->RElink;
 77                 }
 78                 tb=place;
 79             }
 80             if (tb->length>=xk&&tb->flag==0)
 81                 if (tb->length-xk<=minisize)
 82                 {//当搜索到的空间大小<=xk+minisize时,将空间全部分配给作业
 83                     tb->job=job;
 84                     tb->flag=1;
 85                     place=tb->RElink;
 86                     k=1;
 87                     break;
 88                 }
 89                 else
 90                 {//当搜索到的空间大小>xk+minisize时,将空间划分,再分配给作业
 91                     link=getspace(FRtable);
 92                     link->length=tb->length-xk;
 93                     tb->job=job;
 94                     tb->length=xk;
 95                     tb->flag=1;
 96                     link->RElink=tb->RElink;
 97                     if (NULL!=tb->RElink) tb->RElink->FRlink=link;
 98                     tb->RElink=link;
 99                     link->FRlink=tb;
100                     link->job=nil;
101                     link->address=tb->address+xk;
102                     link->flag=0;
103                     place=link;
104                     k=1;
105                     break;
106                 }
107             tb=tb->RElink;
108         }
109     }
110     if (0==k)
111     {//未寻找到合适的空间分区,返回
112         printf(">>空间申请失败! 
");
113         return;
114     }
115 }
116 
117 //主存回收函数,回收作业job所占用的分区空间
118 void reclaim(char job,int choice)
119 {
120     int bool1=0,bool2=0;
121     FRtable *tb,*link;
122     tb=free_table;
123     if (2==choice) link=tb;
124     else link=NULL;
125     do
126     {
127         if (job==tb->job&&1==tb->flag) break;
128         tb=tb->RElink;
129         if (tb==link)
130         {
131             printf("
>>抱歉,不存在作业%c! 
",job);
132             return;
133         }
134     }while(tb!=link);
135     bool1=(NULL==tb->FRlink||tb->FRlink==tb->RElink)? 1:tb->FRlink->flag;
136     bool2=(NULL==tb->RElink||tb->FRlink==tb->RElink)? 1:tb->RElink->flag;
137     if (bool1&&bool2)
138     {
139         tb->job=nil;
140         tb->flag=0;
141     }
142     else if ((NULL==tb->FRlink||1==tb->FRlink->flag)&&0==tb->RElink->flag)
143     {
144         link=tb->RElink;
145         tb->job=nil;
146         tb->length+=link->length;
147         tb->flag=0;
148         tb->RElink=link->RElink;
149         if (NULL!=link->RElink) link->RElink->FRlink=tb;
150         free(link);
151     }
152     else if (0==tb->FRlink->flag&&1==tb->RElink->flag)
153     {
154         link=tb->FRlink;
155         link->length+=tb->length;
156         link->RElink=tb->RElink;
157         tb->RElink->FRlink=link;
158         if (free_table==tb) free_table=link;
159         free(tb);
160     }
161     else if (0==tb->FRlink->flag&&0==tb->RElink->flag)
162     {
163         link=tb->FRlink;
164         link->length=link->length+tb->length+tb->RElink->length;
165         link->RElink=tb->RElink->RElink;
166         if (NULL!=tb->RElink->RElink) tb->RElink->RElink->FRlink=link;
167         if (free_table==tb) free_table=link;
168         free(tb);
169         free(tb->RElink);
170     }
171 }
172 //显示空间分区链表
173 void display(FRtable *tb,int choice)
174 {
175 //    clrscr();
176     FRtable *temp;
177     if (2==choice) temp=tb;
178     else temp=NULL;
179     printf("
	标号	分区首地址	分区大小(KB)	    状态位
");
180     printf("
	 sys	 1024.00	 40.00		     1
");
181     do
182     {
183         printf("
	 %c	 %.2f	 %.2f		     %d
",tb->job,tb->address,tb->length,tb->flag);
184         tb=tb->RElink;
185     }while(temp!=tb);
186 }
187 //主函数
188 int main()
189 {
190     int i,a,choice;
191     float xk;
192     char job;
193     FRtable *ta=getspace(FRtable);
194     free_table=init(ta);
195     do{
196         printf("
 分区分配算法:
	0 - 退出(Exit)
	1 - 首次适应算法(FF)
	2 - 循环首次适应算法(CFF)
 
");
197         printf(">>请选择相应的算法(0-2):");
198         scanf("%d",&choice);
199         if (0==choice) exit(0);
200     }while(0>choice&&2<choice);
201     while(1)
202     {
203         printf("
    菜单:
	0 - 退出(Exit)
	1 - 申请空间(Allocation)
	2 - 回收空间(Reclaim) 
");
204         printf(">>请选择你的操作(0-2):");
205         scanf("%d",&a);
206         switch(a)
207         {
208             //a=0,程序结束
209             case 0:exit(0);
210             //a=1,分配主存空间
211             case 1:printf(">>请输入作业标号和所需要申请的空间:");
212                     scanf("%*c%c%f",&job,&xk);
213                     allocate(job,xk,choice);
214                     display(free_table,choice);
215                     break;
216             //a=2,回收主存空间
217             case 2:printf(">>请输入你想回收的作业的相应标号:");
218                     scanf("%*c%c",&job);
219                     reclaim(job,choice);
220                     display(free_table,choice);
221                     break;
222             default:printf(">>ERROR:No thie choose! 
");
223         }
224     }
225 }

4.运行结果

如上图所示实验已达到预期效果。

实验总结

这次实验做的比较简单,基本实现了预期的功能,一开始对实验的代码不知道怎么处理,通过查阅书本以及问同学,熟悉了算法的原理,并用代码写出来。因为C语言的基础不是很好,所以做这些实验存在一定的难度。

原文地址:https://www.cnblogs.com/VernSean/p/4597187.html