c++模拟实现动态分区存储管理

一、代码

#include<iostream>
#include<vector>
#include<string>
using namespace std;
typedef struct memoryBlock{
    string jobName;
    int startadress;
    int length;
    bool state;
}memoryBlock;
vector<memoryBlock> mb;
void init(){
    memoryBlock m1,m2,m3,m4,m5;
    m1.jobName="作业1";m2.jobName="作业3";m3.jobName="未分配";m4.jobName="作业2";m5.jobName="未分配";
    m1.state=1;m2.state=1;m3.state=0;m4.state=1;m5.state=0;
    m1.startadress=5;m2.startadress=10;m3.startadress=14;m4.startadress=26;m5.startadress=32;
    m1.length=5;m2.length=4;m3.length=12;m4.length=6;m5.length=96;
    mb.push_back(m1);mb.push_back(m2);mb.push_back(m3);mb.push_back(m4);mb.push_back(m5);
}
void firstfit(){
    string name;
    cout<<"请输入要分配的作业名称:";
    cin>>name;
    int size;
    cout<<"请输入作业主存量:";
    cin>>size;
    for(vector<memoryBlock>::iterator it = mb.begin();it!=mb.end();++it){
        int s_pos = it->startadress+size;
        int last_size = it->length-size;
        int f = 0;
        if(it->length>size){
            f=1;
        }
        if(it->state==0&&it->length>=size){
            it->state=1;
            it->length=size;
            it->jobName = name;
            if(f){
                memoryBlock m;
                m.jobName="未分配";
                m.length=last_size;
                m.state=0;
                m.startadress = s_pos;
                it++;
                mb.insert(it,m);
            }
            break;
        }
    }
}
void bestfit(){
    string name;
    cout<<"请输入要分配的作业名称:";
    cin>>name;
    int size;
    cout<<"请输入作业主存量:";
    cin>>size;
    int min_last=128;
    for(vector<memoryBlock>::iterator it = mb.begin();it!=mb.end();++it){
        if(it->state==0&&it->length>=size){
            int last_size = it->length-size;
            if(last_size<min_last){
                min_last=last_size;
            }
        }
    }
    for(vector<memoryBlock>::iterator it = mb.begin();it!=mb.end();++it){
        int s_pos = it->startadress+size;
        int last_size = it->length-size;
        if(last_size==min_last){
            it->state=1;
            it->length=size;
            it->jobName = name;
            if(last_size>0){
                memoryBlock m;
                m.jobName="未分配";
                m.length=last_size;
                m.state=0;
                m.startadress = s_pos;
                it++;
                mb.insert(it,m);
            }
            break;
        }
    }
}
void memoryrecycle(){
    cout<<"请输入要回收的作业名称:";
    string name;
    cin>>name;
    vector<memoryBlock>::iterator it_new;
    for(vector<memoryBlock>::iterator it = mb.begin();it!=mb.end();++it){
        if(it->jobName.compare(name)==0){
            it->state=0;
            it->jobName="未分配";
            it_new = it;
            break;
        }
    }
    vector<memoryBlock>::iterator it_pre=--it_new;
    it_new++;
    vector<memoryBlock>::iterator it_next=++it_new;
    it_new--;
    if(it_pre->state==1&&it_next->state==0){
        it_new->length+=it_next->length;
        mb.erase(it_next);
    }
    else if(it_pre->state==0&&it_next->state==1){
        it_pre->length+=it_new->length;
        mb.erase(it_new);
    }
    else if(it_pre->state==0&&it_next->state==0){
        it_pre->length+=it_new->length;
        it_pre->length+=it_next->length;
        mb.erase(it_new);
        mb.erase(it_next);
    }
}
void showMT(){
    cout<<"*********************空闲区表*********************"<<endl;
    cout<<"\t起止\t|\t长度\t|\t状态"<<endl;
    for(vector<memoryBlock>::iterator it = mb.begin();it!=mb.end();++it){
        if(it->state==0){
            cout<<"\t"<<it->startadress<<"k\t|\t"<<it->length<<"k\t|\t"<<it->jobName<<endl;
        }
    }
    cout<<"**************************************************"<<endl;
    cout<<"*********************已分配表*********************"<<endl;
    cout<<"\t起止\t|\t长度\t|\t名称"<<endl;
    for(vector<memoryBlock>::iterator it = mb.begin();it!=mb.end();++it){
        if(it->state==1){
            cout<<"\t"<<it->startadress<<"k\t|\t"<<it->length<<"k\t|\t"<<it->jobName<<endl;
        }
    }
    cout<<"**************************************************"<<endl;
}
int main(){
    init();
    cout<<"选择分配主存算法(a-首次适应算法,b-最优适应算法)"<<endl<<"请输入选择的算法:";
    char option1;
    cin>>option1;
    int option2;
    int running = 1;
    while(running){
        cout<<"选择功能项(0-退出,1-分配主存,2-回收主存,3-显示主存)"<<endl<<"请输入选择的功能:";
        cin>>option2;
        switch (option2){
            case 0: running = 0;break;
            case 1: {
                if(option1=='a'){
                    firstfit();
                }
                else if(option1=='b'){
                    bestfit();
                }
                break;
            }
            case 2: {memoryrecycle();break;}
            case 3: {showMT();break;}
            default:{
                cout<<"输入有误!请重新选择"<<endl;
                break;
            } 
            
        }
    }
    return 0;
}

二、介绍

编程实现动态分区存储管理方式的主存分配与回收。具体内容包括:首先确定主存空间分配表;然后采用最优适应算法及首次适应算法完成主存空间的分配和回收。

具体讲:

初始状态:动态分区管理方式预先不将主存划分区域。而是把主存除操作系统占用区域外的空间看作一个大的空闲区。当作业要求装入主存时,根据作业的大小查询主存内各空闲区。并按照特定的算法选择一合适的空闲区,按作业大小的要求画出一个分区并装入该作业。剩下的区域作为新的空闲区。

当作业执行完毕后,所占用的主存空间将被回收,成为一个空闲区。注意如果该空闲区的相邻分区也是空闲区,则需要将相邻空闲区合并成一个空闲区。

提示:

动态分区大小由作业需求量决定,分区的长度预先不能固定。

可建立两张分区表记录主存使用情况:

“已分配表”记录作业占用分区;“空闲区表”记录空闲区。

主程序菜单可参考:

    选择功能项(0-退出、1-分配主存、2-回收主存、3-显示主存)

    分配时,要求输入作业名和长度

    回收时,要求输入要回收的作业名

    显示主存,则显示空闲分区情况以及已分配分区情况等。

本实验模拟在两种存储管理方式下的主存分配和回收。

图例:

可变分区方式是按作业需要的主存空间大小来分割分区的。当要装入一个作业时,根据作业需要的主存量查看是否有足够的空闲空间,若有,则按需要量分割一个分区分配给该作业;若无,则作业不能装入。随着作业的装入、撤离,主存空间被分成许多个分区,有的分区被作业占用,而有的分区是空闲的。

为了说明哪些区是空闲的,可以用来装入新作业,必须要有一张空闲区说明表,格式如下:

 

起    址

长    度

状      态

第一栏

14 K

12 K

未 分 配

第二栏

32 K

96 K

未 分 配

其中,起址——指出一个空闲区的主存起始地址。

      长度——指出从起始地址开始的一个连续空闲的长度。

      状态——有两种状态,一种是“未分配”状态,指出对应的由起址指出的某个长度的区域是空闲区;另一种是“空表目”状态,表示表中对应的登记项目是空白(无效),可用来登记新的空闲区(例如,作业撤离后,它所占的区域就成了空闲区,应找一个“空表目”栏登记归还区的起址和长度且修改状态)。由于分区的个数不定,所以空闲区说明表中应有适量的状态为“空表目”的登记栏目,否则造成表格“溢出”无法登记。

上述的这张说明表的登记情况是按例所装入的三个作业占用的主存区域后填写的。

(1) 当有一个新作业要求装入主存时,必须查空闲区说明表,从中找出一个足够大的空闲区。有时找到的空闲区可能大于作业需要量,这时应把原来的空闲区变成两部分:一部分分给作业占用;另一部分又成为一个较小的空闲区。为了尽量减少由于分割造成的空闲区,而尽量保存高地址部分有较大的连续空闲区域,以利于大型作业的装入。为此,在空闲区说明表中,把每个空闲区按其地址顺序登记,即每个后继的空闲区其起始地址总是比前者大。为了方便查找还可使表格“紧缩”,总是让“空表目”栏集中在表格的后部。

(2) 采用最先适应算法(顺序分配算法)分配主存空间。

按照作业的需要量,查空闲区说明表,顺序查看登记栏,找到第一个能满足要求的空闲区。当空闲区大于需要量时,一部分用来装入作业,另一部分仍为空闲区登记在空闲区说明表中。

由于本实验是模拟主存的分配,所以把主存区分配给作业后并不实际启动装入程序装入作业,而用输出“分配情况”来代替。最先适应分配算法如图4-1。

(3) 当一个作业执行结束撤离时,作业所占的区域应该归还,归还的区域如果与其它空闲区相邻,则应合成一个较大的空闲区,登记在空闲区说明表中。例如,在提示(1)中列举的情况下,如果作业2撤离,归还所占主存区域时,应与上、下相邻的空闲区一起合成一个大的空闲区登记在空闲区说明表中。归还主存时的回收算法如图4-2。

(4) 请按最先适应算法设计主存分配和回收的程序。然后按主存中已装入三个作业,且形成两个空闲区,确定空闲区说明表的初值。现有一个需要主存量为6K的作业4申请装入主存;然后作业3撤离;再作业2撤离。请你为它们进行主存分配和回收,把空闲区说明表的初值以及每次分配或回收后的变化显示出来或打印出来。

图1:最先适应分配模拟算法

 
 

图2: 主存回收算法

 
 


 

 

 

 

  • 6
    点赞
  • 102
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
通用动态分区分配存储器管理系统是一个操作系统的重要组成部分,其主要作用是管理计算机的内存资源,有效地分配和回收内存空间,以满足系统的运行需求。以下是一个简单的通用动态分区分配存储器管理系统的设计: 1. 内存分区管理 系统需要维护一个内存分区表,记录可用和已分配的内存分区的信息。每个内存分区表项包括以下信息: - 分区大小 - 起始地址 - 是否已分配 系统需要实现内存分区的分配和回收操作。分配操作根据分配请求的大小,从可用分区中选择合适的分区进行分配。回收操作将已分配的分区释放,并将该分区标记为可用。 2. 内存分配算法 系统需要实现不同的内存分配算法,以满足不同的应用场景需求。常见的内存分配算法包括: - 首次适应算法:按照分区起始地址从低到高的顺序查找,找到第一个符合大小要求的空闲分区进行分配。 - 最佳适应算法:按照分区大小从小到大的顺序查找,找到最小的符合大小要求的空闲分区进行分配。 - 最坏适应算法:按照分区大小从大到小的顺序查找,找到最大的符合大小要求的空闲分区进行分配。 3. 内存碎片整理 随着内存的不断分配和回收,可能会产生很多小的空闲分区,导致内存碎片化。系统需要实现内存碎片整理算法,将多个小的空闲分区合并成一个大的空闲分区,以充分利用内存资源。 4. 进程内存管理 对于每个进程,系统需要维护其内存使用情况,包括已分配的内存大小和起始地址。当进程需要更多内存时,系统需要为其分配新的内存分区,当进程不需要某些内存时,系统需要回收这些内存分区。 5. 内存保护 系统需要实现内存保护机制,防止一个进程越界访问另一个进程的内存空间,或者访问操作系统内存空间。系统可以通过硬件机制(如MMU)或软件机制(如地址转换和访问权限控制)来实现内存保护。 以上是一个简单的通用动态分区分配存储器管理系统的设计。实现这个系统需要考虑各种不同的情况和应用场景,需要仔细设计和测试,确保其稳定性和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值