实验四主存空间的分配和回收
网络工程专业 姓名:蔡利聪 学号:201306114117
一、目的和要求
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(">>空间申请失败! \n");
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("\n>>抱歉,不存在作业%c! \n",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("\n\t标号\t分区首地址\t分区大小(KB)\t 状态位\n");
180 printf("\n\t sys\t 1024.00\t 40.00\t\t 1\n");
181 do
182 {
183 printf("\n\t %c\t %.2f\t %.2f\t\t %d\n",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("\n 分区分配算法:\n\t0 - 退出(Exit)\n\t1 - 首次适应算法(FF)\n\t2 - 循环首次适应算法(CFF)\n \n");
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("\n 菜单:\n\t0 - 退出(Exit)\n\t1 - 申请空间(Allocation)\n\t2 - 回收空间(Reclaim) \n");
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! \n");
223 }
224 }
225 }
4.运行结果

如上图所示,当输入需要申请的空间和标号后,空闲分区会分配相应的空间大小,当输入回收的标号时,内存会回收相应大小的空间。根据实验结果显示,实验已达到预期效果。
四、实验总结
(1)本次实验是有关内存空间分配的算法的实现,实验内容相对之前的进程调度稍微简洁些,但是基本实现的数据结构的链表算法是一样的,还是需要通过申请空间,定义分区大小,然后通过链表对各空闲分区进行相应的内存分配。
(2)虽然对实验步骤比较清晰,对首次适应算法、循环首次适应算法的知识理解得比较好,但是在对如何通过这些算法去实现这个内存分配的实验,还是遇到很多困难,比如链表初始化与访问的算法基础掌握得不好,还有一些基本的C语言的语法结构掌握不熟练,而且对算法与与程序之间的思维不清晰,导致在写程序中出现较多问题,然后通过查找课本,上网搜寻资料,询问同学进行帮助解答,最后得到基本的实验程序。
来源:https://www.cnblogs.com/clcbk/p/4550955.html