最优适应算法

来源:互联网 发布:康师傅冰糖雪梨知乎 编辑:程序博客网 时间:2024/04/30 05:45

 

【问题描述】编写程序,采用最优适应算法实现可变分区存储管理方式的主存分配及回收。设计具体包括:首先构造主存空间分配表,然后完成主存空间的分配和回收;最后编写主函数对所做工作进行测试。

【提示】动态构造主存空间分配表,包括已占分区表和空闲区表。根据申请,实施内存分配,并返回分配所得内存首址;分配完后,调整空闲区表(即扣除分配部分),并显示调整后的空闲区表;若分配失败,返回分配失败信息。回收空间时,按内存回收的四种情况从键盘接收回收区域的内存首址与大小,调整空闲区表(与前、后空闲区相连则合并再插入该项),并显示调整后的空闲区表。

 

程序代码如下:

//内存管理----最优适应分配算法
#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