基于动态分区分配的存储器管理系统(首次适应算法、循环首次适应算法、最佳适应算法、最坏适应算法)

//基于动态分区分配的存储器管理系统的设计与实现
#include <bits/stdc++.h>
using namespace std;
int N;//定义空闲分区最大值
//定义空闲分区
struct Block {
    //分区id、开始地址、分区大小、使用状态(free/busy)、后继指针、前驱指针
    int Block_id;
    int Address_start,Block_size;
    bool Use_state;
    Block *next,*pre;
};
Block *head;//头节点
Block *tail;//尾节点
Block *last;//上次查找结束的节点位置,初始位置为head节点,循环首次算法中用到,定义为全局变量,创建空闲链表时首次指向head节点
//创建双向链表,头节点为空
void Create_list(){
    head=new Block();
    tail=new Block();
    last=new Block();
    head->next=tail;
    head->pre=NULL;
    tail->next=NULL;
    tail->pre=head;
    last=head;//创建空闲链表时首次指向head节点
    tail->Block_id=0;
    tail->Address_start=0;
    tail->Block_size=N;
    tail->Use_state=0;
}
//算法1首次适应算法
bool First_fit(int id,int request){
    Block *memory=new Block();
    memory->Block_id=id;
    memory->Block_size=request;
    memory->Use_state=1;
    //创建memory节点并赋值,记录分配请求
    Block *p=head->next;//每次从头开始扫描链表
    while (p){
        if (!p->Use_state){
            //情况1空闲链表中存在大小与请求相等的分区
            if (p->Block_size==request){
                p->Block_id=id;
                p->Use_state=1;//更新空闲链表
                return true;
            }
            //情况2空闲链表中存在大小大于请求相等的分区
            else if (p->Block_size>request){
                memory->pre=p->pre;
                p->pre->next=memory;
                memory->next=p;
                p->pre=memory;//参考文献,插入节点是前驱节点,需遵循从左往右原则,实现memory节点的插入
                memory->Address_start=p->Address_start;
                p->Address_start=memory->Address_start+memory->Block_size;//更新分区的首地址
                memory->Use_state=1;//更新分区使用状态
                p->Block_size-=request;//更新空闲分区的大小
                return true;
            }
        }
        p=p->next;//没有满足分配请求的分区大小则继续指针后移
    }
    return false;//遍历结束,未找到合适的空闲分区,分配请求失败
}
//算法2循环首次适应算法
bool Next_fit(int id,int request){
    //使用循环链表
    Block *memory=new Block();
    memory->Block_id=id;
    memory->Block_size=request;
    memory->Use_state=1;
    Block *p=last->next;
    while (p!=last){
        if (p->next==NULL)p->next=head->next;//循环链表,首尾相连
        if (!p->Use_state){
            if (p->Block_size==request){
                p->Block_id=id;
                p->Use_state=1;
                last=p;//结束时更新last位置
                return true;
            }
            else if (p->Block_size>request){
                memory->pre=p->pre;
                p->pre->next=memory;
                memory->next=p;
                p->pre=memory;//参考文献,插入节点是前驱节点,需遵循从左往右原则,实现memory节点的插入
                memory->Address_start=p->Address_start;
                p->Address_start+=request;//更新首地址
                memory->Use_state=1;//更新分区使用状态
                p->Block_size-=request;//更新last的大小
                last=p;//更新index位置
                return true;
            }
        }
        p=p->next;//没有满足分配请求的分区大小则继续指针后移
    }
    return false;
}
//算法3最佳适应算法
bool Best_fit(int id,int request){
    int minimum=0x3f3f3f3f;//记录大小合适的最小空闲分区块
    Block *memory=new Block();
    memory->Block_id=id;
    memory->Block_size=request;
    memory->Use_state=1;
    Block *p=head->next;
    Block *index=NULL;//记录找到的最小空闲分区的位置
    int flag=0;//标记分区相等或大于的情况,1表示相等,2表示大于,0表示未找到合适空闲分区
    while (p){
        if (!p->Use_state){
            if (p->Block_size==request){
                p->Block_id=id;
                p->Use_state=1;
                index=p;//更新index位置
                flag=1;
                return true;
            }
            else if (p->Block_size>request){
                if (p->Block_size<minimum){
                    minimum=p->Block_size;
                    index=p;//更新index位置
                    flag=2;
                }
            }
        }
        p=p->next;//指针后移,继续遍历空闲链表
    }
    if (!flag)return 0;//没有找到合适的空闲分区
    else {
        if (flag==2){
            memory->pre=index->pre;
            index->pre->next=memory;
            memory->next=index;
            index->pre=memory;//参考文献,插入节点是前驱节点,需遵循从左往右原则,实现memory节点的插入
            memory->Address_start=index->Address_start;
            index->Address_start+=request;//更新首地址
            memory->Use_state=1;//更新分区使用状态
            index->Block_size-=request;//更新index的大小
        }
        return true;
    }
}
//算法4最坏适应算法
bool Worst_fit(int id,int request){
    int maximum=-1;//记录大小合适的最大空闲分区块
    Block *memory=new Block();
    memory->Block_id=id;
    memory->Block_size=request;
    memory->Use_state=1;
    Block *p=head->next;
    Block *index=NULL;//记录找到的最大空闲分区的位置
    int flag=0;//标记分区相等或大于的情况,1表示相等,2表示大于,0表示未找到合适空闲分区
    while (p){
        if (!p->Use_state){
            if (p->Block_size==request){
                p->Block_id=id;
                p->Use_state=1;//更新空闲链表
                flag=1;
                return true;
            }
            else if (p->Block_size>request){
                if (p->Block_size>maximum){
                    maximum=p->Block_size;
                    index=p;//更新index位置
                    flag=2;
                }
            }
        }
        p=p->next;//指针后移,继续遍历空闲链表
    }
    if (!flag)return false;//没有找到合适的空闲分区
    else {
        if (flag==2){
            memory->pre=index->pre;
            index->pre->next=memory;
            memory->next=index;
            index->pre=memory;//参考文献,插入节点是前驱节点,需遵循从左往右原则,实现memory节点的插入
            memory->Address_start=index->Address_start;
            index->Address_start+=request;//更新首地址
            memory->Use_state=1;//更新分区使用状态
            index->Block_size-=request;//更新index的大小
        }
        return true;
    }
}
//操作1分配内存
bool Allocate(int choice,int id,int request){
    if (request>0){
       if (choice==1){
          if (First_fit(id,request))return true;
          else return false;
       }else if (choice==2){
          if (Next_fit(id,request))return true;
          else return false;
       }else if (choice==3){
          if (Best_fit(id,request))return true;
          else return false;
       }else if (choice==4){
          if (Worst_fit(id,request))return true;
          else return false;
       }
    }else {
        cout<<"分配大小无效,请重新输入!"<<"\n";
        return false;
    }
}
//操作2回收内存
void Recycle(int id){
    Block *p=head->next;
    while (p){
        if (p->Block_id==id){
            p->Block_id=0;
            p->Use_state=0;
            /*内存合并包括四种情况
             1、空闲分区前后都没有空闲分区
             2、仅有空闲分区前面有空闲分区
             3、仅有空闲分区后面有空闲分区
             4、空闲分区前后都有空闲分区
            */
            //内存合并,当前面存在空闲分区时就进行合并
            //当遇到前面是头节点或后面没有结点时这两种时,需进行特判
            if (p->pre==head)continue;
            else if (!p->pre->Use_state){
                p->pre->Block_size+=p->Block_size;
                p->pre->next=p->next;
                p->next->pre=p->pre;
            }
            //内存合并,当后面有空闲分区时就进行合并
            if (p->next==NULL)continue;
            else if (!p->next->Use_state){
                p->Block_size+=p->Block_size;
                p->next->next->pre=p;
                p->next=p->next->next;
            }
            break;
        }
        p=p->next;
    }
}
//操作3查看当前内存分配情况
void View(){
    cout<<"———当前内存分配情况———"<<"\n";
    Block *p=head->next;
    while (p){
        cout<<"作业号:";
        if (!p->Block_id)cout<<"Free"<<"\n";
        else cout<<p->Block_id<<"\n";
        cout<<"起始地址:"<<p->Address_start<<"\n";
        cout<<"分区大小:"<<p->Block_size<<"\n";
        cout<<"使用状态:";
        if (!p->Use_state)cout<<"Free"<<"\n";
        else cout<<"Busy"<<"\n";
        cout<<"——————————————"<<"\n";
        p=p->next;
    }
}
//主函数
int main(){
    while(1){
        bool initial=true;//标记初始状态
        cout<<"———基于动态分区分配的存储器管理系统———"<<"\n";
        cout<<"|            退出系统请按0                 |"<<"\n";
        cout<<"|       本系统支持以下四种算法:           |"<<"\n";
        cout<<"|          1、首次适应算法                 |"<<"\n";
        cout<<"|          2、循环首次适应算法             |"<<"\n";
        cout<<"|          3、最佳适应算法                 |"<<"\n";
        cout<<"|          4、最坏适应算法                 |"<<"\n";
        cout<<"——————————————————————"<<"\n";
        cout<<"您好!当前您已进入分配算法选择模块!"<<"\n";
        int choice;
        while (1){
            cout<<"请输入您选择的分配算法编号:";
            cin>>choice;
            cout<<"请输入初始空间大小:";
            cin>>N;
            cout<<"\n";
            if (!choice){
                cout<<"即将退出系统!"<<"\n";
                return 0;
            }
            if (choice<0||choice>4){
            cout<<"输入无效,请重新输入!"<<"\n";
            continue;
            }
            else break;
        }
        if (initial){
            Create_list();//创建链表
            initial=false;
        }
        cout<<"分配算法选择完成!"<<"\n";
        cout<<"———本系统支持以下4种操作:———"<<"\n";
        cout<<"|         1、分配内存            |"<<"\n";
        cout<<"|         2、回收内存            |"<<"\n";
        cout<<"|       3、查看当前内存分配情况  |"<<"\n";
        cout<<"|         0、结束操作            |"<<"\n";
        cout<<"—————————————————"<<"\n";
        cout<<"您好!当前您已进入操作选择模块!"<<"\n";
        int operate;
        while (1){
            cout<<"请输入您选择的操作编号:";
            cin>>operate;
            if (!operate){
                cout<<"操作结束!"<<"\n";
                View();
                break;
            }else if (operate==1){
                int id,request;//请求分配的作业号及分配内存的大小
                cout<<"请输入作业号、请求分配的内存大小"<<"\n";
                cin>>id>>request;
                if (Allocate(choice,id,request)){
                    cout<<"分配成功!"<<"\n";
                    //数据永久保存,写入文件
                    fstream fs; //可输入输出
                    //指定文件打开方式
                    fs.open("D:\\DTFQFPsystem.txt", ios::out|ios::app);
                    //文件写入
                    fs<<"当前操作信息如下:"<<"所选算法:"<<choice<<" "<<"所选操作:"<<operate<<" "<<"作业号:"<<id<<" "<<"请求:"<<request<<"\n";
                    fs<<"当前内存信息如下:分配成功!"<<"\n";
                    Block *p=head->next;
                    while (p){
                        fs<<"作业号:";
                        if (!p->Block_id)fs<<"Free"<<" ";
                        else fs<<p->Block_id<<"\n";
                        fs<<"起始地址:"<<p->Address_start<<" ";
                        fs<<"分区大小:"<<p->Block_size<<" ";
                        fs<<"使用状态:";
                        if (!p->Use_state)fs<<"Free"<<"\n";
                        else fs<<"Busy"<<"\n";
                        p=p->next;
                    }
                    fs.close();
                }
                else {
                    cout<<"分配失败!"<<"\n";
                    //数据永久保存,写入文件
                    fstream fs; //可输入输出
                    //指定文件打开方式
                    fs.open("D:\\DTFQFPsystem.txt", ios::out|ios::app);
                    //文件写入
                    fs<<"当前操作信息如下:"<<"所选算法:"<<choice<<" "<<"所选操作:"<<operate<<" "<<"作业号:"<<id<<" "<<"请求:"<<request<<"\n";
                    fs<<"当前内存信息如下:分配失败!"<<"\n";
                    Block *p=head->next;
                    while (p){
                        fs<<"作业号:";
                        if (!p->Block_id)fs<<"Free"<<" ";
                        else fs<<p->Block_id<<"\n";
                        fs<<"起始地址:"<<p->Address_start<<" ";
                        fs<<"分区大小:"<<p->Block_size<<" ";
                        fs<<"使用状态:";
                        if (!p->Use_state)fs<<"Free"<<"\n";
                        else fs<<"Busy"<<"\n";
                        p=p->next;
                    }
                    fs.close();
                }
                View();
            }else if (operate==2){
                int id;
                cout<<"请输入释放作业号:";
                cin>>id;
                Recycle(id);//回收内存
                //数据永久保存,写入文件
                fstream fs; //可输入输出
                //指定文件打开方式
                fs.open("D:\\DTFQFPsystem.txt", ios::out|ios::app);
                //文件写入
                fs<<"当前操作信息如下:"<<"所选算法:"<<choice<<" "<<"所选操作:"<<operate<<" "<<"作业号:"<<id<<"\n";
                fs<<"当前内存信息如下:"<<"\n";
                Block *p=head->next;
                while (p){
                    fs<<"作业号:";
                    if (!p->Block_id)fs<<"Free"<<" ";
                    else fs<<p->Block_id<<" ";
                    fs<<"起始地址:"<<p->Address_start<<" ";
                    fs<<"分区大小:"<<p->Block_size<<" ";
                    fs<<"使用状态:";
                    if (!p->Use_state)fs<<"Free"<<"\n";
                    else fs<<"Busy"<<"\n";
                    p=p->next;
                }
                fs.close();
                View();
            }else if (operate==3){
                View();//查看当前内存分配情况
            }else {
                cout<<"输入无效,请重新输入!"<<"\n";
                continue;
            }
        }
    }
    return 0;
}

 

posted @ 2023-06-18 22:52  好腻友Π  阅读(503)  评论(0)    收藏  举报