【问题描述】编写程序,采用最优适应算法实现可变分区存储管理方式的主存分配及回收。设计具体包括:首先构造主存空间分配表,然后完成主存空间的分配和回收;最后编写主函数对所做工作进行测试。
【提示】动态构造主存空间分配表,包括已占分区表和空闲区表。根据申请,实施内存分配,并返回分配所得内存首址;分配完后,调整空闲区表(即扣除分配部分),并显示调整后的空闲区表;若分配失败,返回分配失败信息。回收空间时,按内存回收的四种情况从键盘接收回收区域的内存首址与大小,调整空闲区表(与前、后空闲区相连则合并再插入该项),并显示调整后的空闲区表。
程序代码如下:
//内存管理----最优适应分配算法
#include<iostream>
#include<string>
#include<list>
#include<iomanip>
#define MemSize 1024 //定义内存大小
#define MemBassaddr 0 //定义内存起始地址
using namespace std;
struct freepartion//空闲分区结构定义
{
int baseaddr;//空闲分区的起始地址
int partionlen;//空闲分区的长度
};
struct usedpartion//已分配的内存分区结构定义
{
string jobname;//作业名
int baseaddr; //作业所占分区的起始地址
int partionlen;//作业所占分区的长度
};
list<freepartion>freetable;//空闲分区表
list<usedpartion>usedtable;//已分配分区表
void AllocateMem(string &jobname,int &joblen)//采用最优适应分配算法为作业jobname分配joblen大小的空间
{
//要分配的作业名不能为已存在的作业名
list<usedpartion>::iterator used=usedtable.begin();
while(used!=usedtable.end())
{
if(used->jobname==jobname)
{
cout<<"作业已存在,不能再分配一个相同名的作业!"<<endl;
return;
}
else
{
used++;
}
}
//最优适应分配算法
list<freepartion>::iterator it=freetable.begin();
if(it==freetable.end())
{
cout<<"空闲分区已用完!"<<endl;
return;
}
list<freepartion>::iterator itfreetmp=it;
while(it!=freetable.end())
{
if(it->partionlen>=joblen)
{
if(itfreetmp->partionlen>it->partionlen)
{
itfreetmp=it;
it++;
continue;
}
else if(itfreetmp->partionlen<joblen)
{
itfreetmp=it;
it++;
continue;
}
else
{
it++;
continue;
}
}
else
{
it++;
}
}//while
if(itfreetmp->partionlen>=joblen)
{
//修改已分配分区表
usedpartion tempuse;
tempuse.baseaddr=itfreetmp->baseaddr;
tempuse.jobname=jobname;
tempuse.partionlen=joblen;
usedtable.push_back(tempuse);
//从空闲区分配空间
if(itfreetmp->partionlen==joblen)
{
freetable.erase(itfreetmp);
}
else
{
itfreetmp->baseaddr=itfreetmp->baseaddr+joblen;
itfreetmp->partionlen=itfreetmp->partionlen-joblen;
}
cout<<"为作业"<<jobname<<"分配内存成功!"<<endl;
return;
}
else
{
cout<<"内存不足,为作业分配内存失败!"<<endl;
return;
}
}
void ReclaimMem(string jobname)//回收作业jobname所占的内存
{
list<usedpartion>::iterator itused=usedtable.begin();
list<freepartion>::iterator itfree=freetable.begin();
freepartion free;
while(itused!=usedtable.end())
{
if(itused->jobname==jobname)//找到要回收的作业
{
free.baseaddr=itused->baseaddr;
free.partionlen=itused->partionlen;
usedtable.erase(itused);
if(itfree!=freetable.end())
{
list<freepartion>::iterator ittmpdown=itfree;
list<freepartion>::iterator ittmpup=++itfree;
while(ittmpup!=freetable.end())
{
if(free.baseaddr==(ittmpdown->baseaddr+ittmpdown->partionlen))//下邻空闲区
{
if(free.baseaddr+free.partionlen==ittmpup->baseaddr)//下邻空闲区,上邻空闲区
{
ittmpdown->partionlen=ittmpdown->partionlen+free.partionlen+ittmpup->partionlen;
freetable.erase(ittmpup);//删除上邻空闲区
cout<<"回收作业所占的内存成功!"<<endl;
return;
}
else//下邻空闲区,但不上邻空闲区
{
ittmpdown->partionlen=ittmpdown->partionlen+free.partionlen;
cout<<"回收作业所占的内存成功!"<<endl;
return;
}
}
else if(free.baseaddr+free.partionlen==ittmpup->baseaddr)//上邻空闲区,但不下邻空闲区
{
ittmpup->baseaddr=free.baseaddr;
ittmpup->partionlen=free.partionlen+ittmpup->partionlen;
cout<<"回收作业所占的内存成功!"<<endl;
return;
}
else//既不下邻空闲区又不上邻空闲区
{
if((free.baseaddr<ittmpup->baseaddr)&&(free.baseaddr>ittmpdown->baseaddr))//位于空闲区中间
{
freetable.insert(ittmpup,free);
cout<<"回收作业所占的内存成功!"<<endl;
return;
}
else
{
if(free.baseaddr<ittmpdown->baseaddr)//小于空闲区下限
{
freetable.insert(ittmpdown,free);
cout<<"回收作业所占的内存成功!"<<endl;
return;
}
else//大于空闲区上限
{
ittmpdown=ittmpup;
itfree++;
ittmpup=itfree;
continue;
}
}//
}//else既不下邻空闲区又不上邻空闲区
}//while
if(ittmpup==freetable.end())
{
if(ittmpdown->baseaddr>free.baseaddr)
{
if(free.baseaddr+free.partionlen==ittmpdown->baseaddr)//上邻空闲区
{
ittmpdown->baseaddr=free.baseaddr;
ittmpdown->partionlen=ittmpdown->partionlen+free.partionlen;
cout<<"回收作业所占的内存成功!"<<endl;
return;
}
else//不上邻空闲区
{
freetable.insert(ittmpdown,free);
cout<<"回收作业所占的内存成功!"<<endl;
return;
}
}
else
{
if(ittmpdown->baseaddr+ittmpdown->partionlen==free.baseaddr)//下邻空闲区
{
ittmpdown->partionlen=ittmpdown->partionlen+free.partionlen;
cout<<"回收作业所占的内存成功!"<<endl;
return;
}
else
{
freetable.push_back(free);
cout<<"回收作业所占的内存成功!"<<endl;
return;
}
}
}//if(ittmpup==freetable.end())
/*else//没有遍历到空闲区表的末尾就已更新表
{
cout<<"回收作业所占的内存成功!"<<endl;
return;
}*/
}//if(itfree!=NULL)
else//空闲分区表为空
{
freetable.push_back(free);
cout<<"回收作业所占的内存成功!"<<endl;
return;
}
}//if(itused...)
else //未找到要回收的作业
{
itused++;
}
}//while
if( itused==usedtable.end())
{
cout<<"未找到要回收的作业,请确定所输入的作业名是否正确!"<<endl;
}
}
//主函数
int main()
{
//初始化空闲分区表
freepartion tempfree;
tempfree.baseaddr=MemBassaddr;
tempfree.partionlen=MemSize;
freetable.push_back(tempfree);
//对内存进行管理
int number(5);//管理操作的序号(如下所示)
while(1)
{
if(number==5)
{
cout<<"内存管理操作(最优适应分配算法):"<<endl;
cout<<"---------------------------"<<endl;
cout<<"【0】退出程序"<<endl;
cout<<"【1】为作业分配主存"<<endl;
cout<<"【2】回收作业所占的主存"<<endl;
cout<<"【3】显示空闲分区表"<<endl;
cout<<"【4】显示已分配分区表"<<endl;
cout<<"【5】返回管理操作界面"<<endl;
cout<<"---------------------------"<<endl;
}
cout<<"请选择一个正确的管理序号操作:";
cin>>number;
if(cin.fail())
{
system("cls");
cout<<"输入错误,请仅输入数字!"<<endl;
cin.clear(); //清除std::cin的错误状态
cin.sync(); //清空输入缓冲区
continue;
}
string jobname;
int joblen;
list<freepartion>::iterator itfree=freetable.begin();
list<usedpartion>::iterator itused=usedtable.begin();
int i=0;//分区号从零开始
int j=0;//已分配分区表的分区号从零开始
switch(number)
{
case 0:exit(0);break;
case 1:
cout<<"输入作业名和作业所需长度: ";
cin>>jobname>>joblen;
if(cin.fail())
{
cout<<"输入错误,请重新正确输入!"<<endl;
break;
}
if(joblen<-0)
{
cout<<"作业长度小于或等于零!"<<endl;
break;
}
AllocateMem(jobname,joblen);
break;
case 2:
cout<<"输入要回收的作业名:";
cin>>jobname;
ReclaimMem(jobname);
break;
case 3:
cout<<endl<<"空闲分区表状态如下:/n空闲分区号/t起始地址/t分区长度/n";
while(itfree!=freetable.end())
{
cout<<setw(5)<<i<<'/t'<<'/t'<<setw(5)<<itfree->baseaddr<<'/t'<<'/t'<<setw(5)<<itfree->partionlen<<'/t'<<endl;
i++;
itfree++;
}
break;
case 4:
cout<<endl<<"已分配分区表状态如下:/n作业名/t起始地址/t分区长度/n";
while(itused!=usedtable.end())
{
cout<<setw(5)<<itused->jobname<<'/t'<<itused->baseaddr<<'/t'<<'/t'<<itused->partionlen<<endl;
j++;
itused++;
}
break;
case 5:
system("cls");
break;
default:
cout<<"输入错误,没有这个选项"<<endl;
break;
}//swich
cin.clear(); //清除std::cin的错误状态
cin.sync(); //清空输入缓冲区
}//while(1)
return EXIT_SUCCESS;
}
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/sun_top/archive/2009/12/20/5043670.aspx