实验四 主存空间的分配和回收
一、目的和要求
1.1. 实验目的
用高级语言完成一个主存空间的分配和回收程序,以加深对动态分区分配方式及其算法的理解。
1.2. 实验要求
采用连续分配方式之动态分区分配存储管理,使用首次适应算法、循环首次适应算法、最佳适应算法和最坏适应算法4种算法完成设计(任选两种算法)。
(1)**设计一个作业申请队列以及作业完成后的释放顺序,实现主存的分配和回收。采用分区说明表进行。
(2)或在程序运行过程,由用户指定申请与释放。
(3)设计一个空闲区说明表,以保存某时刻主存空间占用情况。把空闲区说明表的变化情况以及各作业的申请、释放情况显示。
二、实验内容
根据指定的实验课题,完成设计、编码和调试工作,完成实验报告。
三、 实验环境
可以选用Turbo C作为开发环境。也可以选用Windows下的VB,CB或其他可视化环境,利用各种控件较为方便。自主选择实验环境。
四、实验过程与结果
#include"stdio.h" #include"stdlib.h" struct{float startaddress; /*已分分区起始地址*/float length; /*已分分区长度,*/int flag; /*已分配区表登记栏标志,用"0"表示空栏目*/ }used_table[10]; /*已分配区表*/struct{float startaddress; /*空闲区起始地址*/float length; /*空闲区长度*/int flag; /*空闲区表登记栏标志,用"0"表示空栏目,用"1"表示未分配*/ }free_table[10]; /*空闲区表*/void input(); int CyclicAdaptation(char str,float leg,int pre);//分配主存空间函数循环适应 void FirstAdaptation(char str,float leg);//分配主存空间函数首次适应 void reclaim(char str);//回收主存函数void input() {int i;printf("\n 输出空闲区表 \n起始地址 分区长度 标志\n");for(i=0;i<10;i++){printf("%6.0f%9.0f%6d\n",free_table[i].startaddress,free_table[i].length, free_table[i].flag);}printf("\n 按任意键,输出已分配区表\n");getchar();printf("\n 输出已分配区表 \n起始地址 分区长度 标志\n");for(i=0;i<10;i++){if(used_table[i].flag!=0)printf("%6.0f%9.0f%6c\n",used_table[i].startaddress,used_table[i].length, used_table[i].flag);elseprintf("%6.0f%9.0f%6d\n",used_table[i].startaddress,used_table[i].length, used_table[i].flag);} } int uflag;//分配表标志 int fflag;//空闲表标志 int CyclicAdaptation(char str,float leg,int pre) {fflag=0;int k,i;for(i=pre;i<10;i++){if(free_table[i].flag==1 && free_table[i].length>=leg){fflag=1;break;}}if(fflag==0)printf("\n 没有满足条件的空闲区\n");else{ for(k=0;k<10;k++){if(used_table[k].flag==0){used_table[k].length=leg;used_table[k].startaddress=free_table[i].startaddress;used_table[k].flag=str;free_table[i].startaddress=free_table[i].startaddress+leg;free_table[i].length=free_table[i].length-leg;free_table[i].flag=1;break;}}}return i; } void FirstAdaptation(char str,float leg) {fflag=0;int k,i;for(i=0;i<10;i++){if(free_table[i].flag==1 && free_table[i].length>=leg){fflag=1;break;}}if(fflag==0)printf("\n 没有满足条件的空闲区\n");else{for(k=0;k<10;k++){if(used_table[k].flag==0){used_table[k].length=leg;used_table[k].startaddress=free_table[i].startaddress;used_table[k].flag=str;free_table[i].startaddress=free_table[i].startaddress+leg;free_table[i].length=free_table[i].length-leg;free_table[i].flag=1;break;}}}} void reclaim(char str) {float uend_address;float fend_address;uflag=0;fflag=0;int k,i;for(k=0;k<10;k++){if(used_table[k].flag==str){uflag=1;break;}}if(uflag==0)printf("\n 找不到该进程!\n");else{for(i=0;i<10;i++){uend_address=used_table[k].startaddress+used_table[k].length;fend_address=free_table[i].startaddress+free_table[i].length;if(used_table[k].startaddress==fend_address)//上邻 {fflag=1;free_table[i].length=free_table[i].length+used_table[k].length;free_table[i].flag=1;used_table[k].flag=0;used_table[k].length=0;used_table[k].startaddress=0;printf("\n已回收!\n");break;}else{if(free_table[i].startaddress==uend_address)//下邻 {fflag=1;free_table[i].startaddress=used_table[k].startaddress;free_table[i].length=free_table[i].length+used_table[k].length;free_table[i].flag=1;used_table[k].flag=0;used_table[k].length=0;used_table[k].startaddress=0;printf("\n已成功!\n");break;}}}if(fflag==0)//上下领都没有空闲 {i=0;for(i=0;i<10;i++){if(free_table[i].flag==0){free_table[i].startaddress=used_table[k].startaddress;free_table[i].length=used_table[k].length;free_table[i].flag=1;used_table[k].length=0;used_table[k].flag=0;used_table[k].startaddress=0;break;}}printf("\n已成功!\n");}} }int main() {int i;float length;char name; /*空闲分区表初始化:*/int algorithm;int operate;int pre=0;//循环首次适应算法的前一次扫描空闲表处,初始为0free_table[0].startaddress=5120;free_table[0].length=51200;free_table[0].flag=1;for(i=1;i<10;i++)free_table[i].flag=0;/*已分配表初始化:*/for(i=0;i<10;i++)used_table[i].flag=0;input();printf("\n Please choose algorithm 1.首次适应算法 2.循环首次适应算法\n");scanf("%d",&algorithm);if(algorithm==1){while(1){printf("\n Please choose operation 1.分配 2.回收\n");scanf("%d",&operate);if(operate==1){/*a=1分配主存空间*/printf("\n 输入进程名和作业所需长度: ");scanf("%*c%c%f",&name,&length);FirstAdaptation(name,length);/*分配主存空间*/}else{/*a=2回收主存空间*/printf("\n 输入要回收分区的进程名: ");scanf("%*c%c",&name);reclaim(name);/*回收主存空间*/}input();}}else{while(1){printf("\n Please choose operation 1.分配 2.回收\n");scanf("%d",&operate);if(operate==1){/*a=1分配主存空间*/printf("\n 输入进程名和作业所需长度: ");scanf("%*c%c%f",&name,&length);pre=CyclicAdaptation(name,length,pre);/*分配主存空间*/}else{/*a=2回收主存空间*/printf("\n 输入要回收分区的进程名: ");scanf("%*c%c",&name);reclaim(name);/*回收主存空间*/}input();}}return 0; }
运行结果:
五、实验总结
主存空间的分配与回收这个实验思路非常清晰,按着思路来编写程序就可以了。参考了别人的一些代码,对主存空间的分配与回收更加熟悉了。