操作系统实验四

实验四主存空间的分配和回收

  • 源代码

#include<stdio.h>  
#include<conio.h>
#include<string.h>
#include<stdlib.h> 
#include<iostream>
using namespace std;

typedef struct freeTable//定义一个空闲区说明表结构  
{     
    int num;	//分区序号    
    long begin; //起始地址    
    long size;  //分区大小    
    int status; //分区状态 
}PART;

typedef struct Node// 线性表的双向链表存储结构 
{    
    PART data;     
    struct Node *prior; //前趋指针   
    struct Node *next;  //后继指针 
}Node,*LinkList;    

LinkList first; //头结点 
LinkList end;   //尾结点  
int flag;		//记录要删除的分区序号   

bool Initblock(int memoryCapacity, int systemMemoryCapacity)//开创带头结点的内存空间链表 
{   

    first=(LinkList)malloc(sizeof(Node));   
    end=(LinkList)malloc(sizeof(Node));   
    first->prior=NULL;   
    first->next=end;   
    end->prior=first;
    end->next=NULL; 
    end->data.num=1;   
    end->data.begin=systemMemoryCapacity;   
    end->data.size=memoryCapacity;   
    end->data.status=0; 
	first->data.num=0;     
    first->data.begin=0;     
    first->data.size=systemMemoryCapacity;     
    first->data.status=1;  
    return true; 
}

//菜单
void menu()
{
    printf("\n                      |------------内存分配和回收------------|\n");
    printf("                 |================================================|\n");
    printf("                 |              0.Exit                            |\n");
    printf("                 |              1.Using First-Fit Method          |\n");
    printf("                 |              2.Using Best-Fit Method           |\n");
    printf("                 |              3.Using Worst-Fit Method          |\n");
    printf("                 |================================================|\n");
}

//分区序号重新排序
void sort() 
{    
    Node *p=first->next,*q;   
    q=p->next;    
    for(;p!=NULL;p=p->next)   
    {     
        for(q=p->next;q;q=q->next)    
        {       
            if(p->data.num>=q->data.num)       
            {          
                q->data.num+=1;        
            }    
        }     
    } 
 } 

//显示主存分配情况 
void show()  
{  
    int flag=0;	//用来记录分区序号    
    Node *p=first;    
    sort();      
    printf("\n\t\t内存使用情况,按起始地址增长排序\n");      
    printf("----------------------------------------------------------\n\n");     
    printf("DeviceNum\tstartAddress\tDeviceCapacity\tDeviceStatus\n\n");     
    while(p)     
    {        
        printf("%d\t\t%d\t\t%d",p->data.num,p->data.begin,p->data.size);         
        if(p->data.status==0) printf("\t\tFREE\n\n");         
        else printf("\t\tUESD\n\n"); 
          p=p->next;      
    }      
    printf("----------------------------------------------------------\n\n"); 
}

//首次适应算法  
bool First_fit(int request) 
{   
    //为申请作业开辟新空间且初始化    
    Node *p=first->next;    
    LinkList temp=(LinkList)malloc(sizeof(Node));    
    temp->data.size=request;   
    temp->data.status=1;   
    p->data.num=1;   
    while(p)   
    {     
        if((p->data.status==0)&&(p->data.size==request))     
        {
            //有大小恰好合适的空闲块       
            p->data.status=1;       
            return true;        
            break;  
             }     
        else if((p->data.status==0) && (p->data.size>request))     
        {
            //有空闲块能满足需求且有剩余        
            temp->prior=p->prior;        
            temp->next=p;         
            temp->data.begin=p->data.begin;        
            temp->data.num=p->data.num;        
            p->prior->next=temp;         
            p->prior=temp;         
            p->data.begin=temp->data.begin+temp->data.size;        
            p->data.size-=request;        
            p->data.num+=1;        
            return true;        
            break;     
        }     
        p=p->next;  
    }
     return false; 
}   

//最佳适应算法  
bool Best_fit(int request) 
{    
    int ch; //记录最小剩余空间    
    Node *p=first;     
    Node *q=NULL; //记录最佳插入位置     
    LinkList temp=(LinkList)malloc(sizeof(Node)); 
     temp->data.size=request;    
     temp->data.status=1;     
     p->data.num=1;     
     while(p) //初始化最小空间和最佳位置    
     {      
         if((p->data.status==0) && (p->data.size>=request) )      
         {          
             if(q==NULL)             
             {              
                 q=p;               
                 ch=p->data.size-request;             
         }          
             else if(q->data.size > p->data.size)          
             {           
                 q=p;            
                 ch=p->data.size-request;          
             }      
         } 
          p=p->next;   
     }    
     if(q==NULL) return false;//没有找到空闲块   
     else if(q->data.size==request)   
     {         
         q->data.status=1;         
         return true;     
     }  
     else   
     {       
         temp->prior=q->prior;      
         temp->next=q;       
         temp->data.begin=q->data.begin;      
         temp->data.num=q->data.num;      
         q->prior->next=temp;      
         q->prior=temp;        
         q->data.begin+=request;      
         q->data.size=ch;      
         q->data.num+=1; 
         return true;   
     }   
     return true; 
}   

//最差适应算法  
bool Worst_fit(int request) 
{      
    int ch; //记录最大剩余空间     
    Node *p=first->next;      
    Node *q=NULL; //记录最佳插入位置      
    LinkList temp=(LinkList)malloc(sizeof(Node));      
    temp->data.size=request;     
    temp->data.status=1;     
    p->data.num=1;      
    while(p) //初始化最大空间和最佳位置      
    {          
        if(p->data.status==0 && (p->data.size>=request) )          
        {             
            if(q==NULL)            
            {                  
                q=p; 
                ch=p->data.size-request;             
            }             
            else if(q->data.size < p->data.size)            
            {             
                q=p;              
                ch=p->data.size-request;            
            }          
        }          
        p=p->next;      
    }      
    if(q==NULL) return false;//没有找到空闲块     
    else if(q->data.size==request)      
    {         
        q->data.size=1;        
        return true;      
    }     
    else      
    {
        temp->prior=q->prior;       
        temp->next=q;        
        temp->data.begin=q->data.begin;       
        temp->data.num=q->data.num;       
        q->prior->next=temp;       
        q->prior=temp;         
        q->data.begin+=request;       
        q->data.size=ch;       
        q->data.num+=1;       
        return true; 
        }      
    return true; 
}   

//分配主存  
bool allocation(int a) 
{    
    int request;//申请内存大小    
    printf("请输入申请分配的主存大小(单位:KB):");    
    scanf("%d",&request);   
    if(request<0 ||request==0)      
    {        
        printf("分配大小不合适,请重试!");       
        return false;     
    }    
    switch(a)   
    {      
    case 1: //默认首次适应算法 
          if(First_fit(request)==true) printf("\t---- allocate succeed! ----");             
          else printf("\t---- out of memory, allocate error! ----");             
          return true;    
          break;      
    case 2: //选择最佳适应算法              
        if(Best_fit(request)==true) printf("\t---- allocate succeed! ----");             
        else printf("\t---- out of memory, allocate error! ----");             
        return true;             
        break;  
    case 3: //选择最差适应算法              
        if(Worst_fit(request)==true) printf("\t---- allocate succeed! ----");             
        else printf("\t---- out of memory, allocate error! ----");             
        return true;    
        break;   
    } 
}

bool deal1(Node *p)//处理回收空间 
{     
    Node *q=first;     
    for(;q!=NULL;q=q->next)    
    {       
        if(q==p)//找到要回收的地址      
        {      
            if(q->prior->data.status==0&&q->next->data.status!=0)     
            {
                q->prior->data.size+=q->data.size;         
                q->prior->next=q->next;         
                q->next->prior=q->prior;         
                q=q->prior;         
                q->data.status=0;          
                q->data.num=flag-1;       
            }        
            if(q->prior->data.status!=0&&q->next->data.status==0)       
            {         
                q->data.size+=q->next->data.size;     
                q->next=q->next->next;         
                q->next->next->prior=q;        
                q->data.status=0;         
                q->data.num=flag;      
            }        
            if(q->prior->data.status==0&&q->next->data.status==0)      
            {    
                q->prior->data.size+=q->data.size;         
                q->prior->next=q->next;         
                q->next->prior=q->prior; 
                q=q->prior;         
                q->data.status=0;          
                q->data.num=flag-1;      
            }         
            if(q->prior->data.status!=0&&q->next->data.status!=0)       
            {    
                q->data.status=0;      
            }      
        }    
    }     
    return true; 
}   

bool deal2(Node *p)//处理回收空间 
{     
    Node *q=first;
    for(;q!=NULL;q=q->next)    
    {       
        if(q==p)      
        {      
            if(q->prior->data.status==0&&q->next->data.status!=0)     
            {    
                q->prior->data.size+=q->data.size;         
                q->prior->next=q->next; 
                 q->next->prior=q->prior;         
                 q=p->prior;         
                 q->data.status=0;          
                 q->data.num=flag-1;       
			}        
            if(q->prior->data.status!=0&&q->next->data.status==0)       
            {         
                q->data.status=0;     
			}        
            if(q->prior->data.status==0&&q->next->data.status==0)      
            {    
                q->prior->data.size+=q->data.size;         
                q->prior->next=q->next;         
                q->next->prior=q->prior;         
                q=q->prior;         
                q->data.status=0;          
                q->data.num=flag-1;      
            }
             if(q->prior->data.status!=0&&q->next->data.status!=0)       
             {    
                 q->data.status=0;      
             }      
        }    
    }     
    return true; 
}   

//主存回收  
bool recovery(int flag) 
{     
    Node *p=first;    
    for(;p!=NULL;p=p->next)     
    {      
        if(p->data.num==flag)     
        {     
            if(p->prior==first)
                {      
                if(p->next!=end)//当前P指向的下一个不是最后一个时       
                {        
                    if(p->next->data.status==0)      //与后面的空闲块相连         
                    {                  
						p->data.size+=p->next->data.size;                 
                        p->next->next->prior=p;                 
                        p->next=p->next->next; 
                        p->data.status=0;                 
                        p->data.num=flag;         
                    }        
                    else p->data.status=0;       
                }      
                if(p->next==end)//当前P指向的下一个是最后一个时       
                {               
                    p->data.status=0;         
                }    
            }
            //结束if(p->prior==block_first)的情况    
            else if(p->prior!=first)    
            {      
                if(p->next!=end) //      
                {        
                    deal1(p);       
                }      
                else
                {       
                    deal2(p);      
				}    
            }//结束if(p->prior!=block_first)的情况   
        }//结束if(p->data.num==flag)的情况   
}    
    printf("\t****回收成功****");    
    return true;    
}  

void main() 
{
	int memoryCapacity;
	int systemMemoryCapacity;
	printf("请输入初始化内存空间:");
	scanf("%d",&memoryCapacity);
	printf("请输入系统空间大小:");
	scanf("%d",&systemMemoryCapacity);
	Initblock(memoryCapacity, systemMemoryCapacity); //开创空间表
	show();
	
    int i;  //操作选择标记     
    int a;//算法选择标记      
       
     while(1)
    {
     menu();
      printf("请选择输入所使用的内存分配算法 (0~3):");  
            scanf("%d",&a);   
     while(a<0||a>3)     
     {        
         printf("\n输入错误,请重新选择输入所使用的内存分配算法 (0~3):");       
         scanf("%d",&a);      
     }
          switch(a)  
          {    
          case 1:printf("\n\t---- Using First-Fit Method: ----\n");
              break;       
          case 2:printf("\n\t---- Using Best-Fit Method: ----\n");
              break;       
          case 3:printf("\n\t---- Using Worst-Fit Method: ----\n");
              break;  
               case 0:printf("\n\t****退出内存分配与回收****\n");
              return;  
          }      
          while(1)      
          {           
              show();          
              printf("\t1: allocation \t2: recovery\t0: exit\n");         
              printf("请输入您的操作:");         
              scanf("%d",&i);         
              if(i==1)            
                  allocation(a); // 分配内存         
              else if(i==2)  // 内存回收         
              {              
                  printf("请输入您要释放的分区号:");             
                  scanf("%d",&flag);             
                  recovery(flag); 
                  }          
              else if(i==0)    
              {    
                  printf("\n退出当前内存分配算法,返回主菜单\n");    
                  break; //退出   
              }          
              else //输入操作有误         
              {              
                  printf("输入有误,请重新输入!");            
                  continue;         
              }     
          } 
     }
}

  • 测试结果
  1. 初始化分配内存

  2. 首次适应算法

  3. 最佳适应算法

  4. 最坏适应算法

  5. 内存回收

posted on 2016-06-24 15:25  17郑培轩  阅读(192)  评论(0编辑  收藏  举报