主存分配回收算法(BF、FF)用C++实现

一、实验目的

本实验主要让大家熟悉主存的各种分配和回收。所谓分配,就是解决多道作业或多进程如何共享主存空间的问题。所谓回收,就是当作业运行完成时,将作业或进程所占用的主存空间归还给系统。主存的分配和回收的实现就是与主存储器的管理方式有关的。通过本实验,帮助学生理解在不同的存储管理方式下,如何实现主存空间的分配与回收。

二、实验原理

(1)可变式分区管理是指在处理作业过程中建立分区,使分区大小正好适合作业的需要,并且分区个数是可以调整的。当要装入一个作业时,根据作业需要的主存量,查看是否有足够的空闲空间,若有,则按需求量分割一部分给作业;若无,则作业等待。随着作业的装入、完成,主存空间被分割成许多大大小小的分区。有的分区被作业占用,有的分区空闲。例如,某时刻主存空间占用情况如图9-1所示。
为了说明哪些分区是空闲的,可以用来装入新作业,必须要有一张空闲区说明表,如表9-1所示。

主存分配回收算法(BF、FF)用C++实现_第1张图片
主存分配回收算法(BF、FF)用C++实现_第2张图片
其中,起始地址指出各空闲区的主存起始地址,长度指出空闲区大小。
主存分配回收算法(BF、FF)用C++实现_第3张图片
由于分区个数不定,所以空闲区说明表中应有足够的空表目项。否则造成溢出,无法登记。
同样,再设一个已分配区表,记录作业或进程的主存占用情况。
(2)当有一个新作业要求装人主存时,必须查空闲区说明表,从中找出一个足够大的空闲区。有时找到的空闲区可能大于作业需求量,这时应将空闲区一分为二。一个分给作业:另一个仍作为空闲区留在空闲区表中。为了尽量减少由于分割造成的碎片,尽可能分配低地址部分的空闲区,将较大空闲区留在高地址端,以利于大作业的装人。为此在空闲区表中,按空闲区首地址从低到高进行登记。为了便于快速查找,要不断地对表格进行紧缩,即让“空表目"项留在表的后部,其分配框图如图9-2所示.
(3)当一个作业执行完成时,作业所占用的分区应归还给系统。在归还时要考虑相邻空闲区合并的问题。作业的释放区与空闲区的邻接分以下4种情况考虑:
A.释放区下邻(低地址邻接)空闲区;
B.释放区上邻(高地址邻接)空闲区;
C.释放区上下都与空闲区邻接;
D.释放区与空闲区不邻接.
首次适应算法回收框图如图9-3所示。
若采用最佳适应算法.则空闲区说明表中的空闲区按其大小排列。
有关最佳适应算法的分配和回收框图由学生自已给出。
(4)请按首次(或最佳)适应算法设计主存分配和回收程序。以图9-1作为主存当前使用的基础,初始化空闲区和已分配区说明表的值。学生自己设计一个作业申请队列以及作业完成后的释放顺序,实现主存的分配与回收。把空闲区说明表的变化情况以及各作业的申请、释放情况显示或打印出来。
主存分配回收算法(BF、FF)用C++实现_第4张图片
主存分配回收算法(BF、FF)用C++实现_第5张图片

三、实验内容

采用可变式分区管理,使用首次和最佳适应算法实现主存的分配和回收。

1.首次适应算法

#include 
#include 
#include 
#include 
#define N 10//空闲区说明表的大小
using namespace std;
int fcount = 0;//未分配的空闲区数量
int bcount = 0;//主存空间占用数

class Block{
     //主存空间的每一个块表示OS/作业/空闲区
    public:    
        string get_name(){
     return name;}
        int get_start_address(){
     return start_address;}
        int get_size(){
     return size;}
        void set_name(string s) {
      name = s; }
        void set_size(int s) {
      size = s; }
        void set_start_address(int s) {
      start_address = s; }    
    private:
        string name;        //每一个块的名字
        int start_address;  //每一个块的起始地址
        int size;           //每一个块的大小
};
class Work: public Block{
     //作业类,从block类继承
    public:
        Work() {
      set_start_address(0); }
        Work(string n, int s){
     //初始化
            set_name(n);
            set_size(s);
            set_start_address(0);
        }
        int get_work_size(){
      return get_size();}
        string get_work_name(){
     return get_name();}
        int get_work_start_address(){
     return get_start_address();}
        void set_work_start_address(int n) {
      set_start_address(n); }
};

Block block[10];//定义一个展示主存空间的数组

class Free_area:public Block{
     //空闲区类,继承于block类
    public:
        Free_area() {
     state = "empty";};
        Free_area(string n, int s1, int s2) {
     //初始化
            set_name(n);
            set_start_address(s1);
            set_size(s2);
            state = "unappropriated";
        }
        string get_free_area_name(){
     return get_name();}
        int get_free_area_start_address(){
     return get_start_address();}
        int get_free_area_size(){
     return get_size();}
        string get_state(){
     return state;}
        void set_free_area_name(string s) {
      set_name(s); }
        void set_free_area_size(int s) {
      set_size(s); }
        void set_free_area_start_address(int s) {
      set_start_address(s); }
        void set_state(string s) {
      state = s; }
    private:
        string state;//空闲区的状态,为未分配或空表目
};

bool cmp(Block a, Block b){
     //sort函数的比较条件,按照起始地址排序
    return a.get_start_address()<b.get_start_address();
}

void addblock_work(Work work){
     //往主存空间中加入作业
    block[bcount].set_name(work.get_work_name());
    block[bcount].set_start_address(work.get_work_start_address());
    block[bcount].set_size(work.get_work_size());
    bcount++;
}

void deleteblock_work(Work work){
     //从主存空间中删除作业
    for (int i = 0; i < bcount; i++)
        if(block[i].get_name()==work.get_work_name())
            for (int j = i; j < bcount-1; j++){
     
                block[j].set_name(block[j + 1].get_name());
                block[j].set_size(block[j + 1].get_size());
                block[j].set_start_address(block[j + 1].get_start_address());
            }
    bcount--;
}

void addblock_free_area(Free_area free_area){
     //往主存空间中加入空闲区
    block[bcount].set_name(free_area.get_free_area_name());
    block[bcount].set_size(free_area.get_free_area_size());
    block[bcount].set_start_address(free_area.get_free_area_start_address());
    bcount++;
}

void deleteblock_free_area(Free_area free_area){
     //从主存空间中删除空闲区
    for (int i = 0; i < bcount; i++)
        if(block[i].get_name()==free_area.get_free_area_name())
            for (int j = i; j < bcount-1; j++){
     
                block[j].set_name(block[j + 1].get_name());
                block[j].set_size(block[j + 1].get_size());
                block[j].set_start_address(block[j + 1].get_start_address());
            }
    bcount--;
}

void show_free_area(Free_area *free_area){
     //打印出空闲区说明表
    cout << "Free area description table:" << endl;
    cout << setw(60) << setfill('-') << left << "-" <<endl;
    cout << setw(20) << setfill(' ') << left << "start_address" << setw(20) << setfill(' ') << left << "free_area_size"<< setw(20) << setfill(' ') << left << "state"<<endl;    
    cout << setw(60) << setfill('-') << left << "-" <<endl;
    for (int i = 0; i < N; i++){
         
        if(free_area[i].get_state()!="empty")
            cout << setw(20) << setfill(' ') << left << free_area[i].get_free_area_start_address() << setw(20) << setfill(' ') << left << free_area[i].get_free_area_size() << setw(20) << setfill(' ') << left << free_area[i].get_state() <<endl;
        else
            cout << setw(40) << setfill(' ') << left <<" "<<setw(20) << setfill(' ') << left << free_area[i].get_state() << endl;
    }
    cout << setw(60) << setfill('-') << left << "-" <<endl;
}

void show_Occupation(){
     //打印出主存空间占用情况
    sort(block, block + bcount, cmp);
    cout << "Occupation of main memory space:" << endl;
    for (int i = 0; i < bcount; i++){
     
        cout << "      ---------------------" <<endl;
        cout << setw(5) << setfill(' ') << right << block[i].get_start_address() << "K"<< "| " << setw(10) << setfill(' ') << right <<block[i].get_name() << "(" << setw(3) << setfill(' ') << left <<block[i].get_size() << "KB) |  " << endl;
    }
    cout << "  256K---------------------" <<endl;
}

void first_fit_assign(Work &work, Free_area *free_area){
     //首次适应算法实现作业的分配
    bool flag;//表示作业是否分配成功
    for (int i = 0; i < fcount; i++){
     
        if(free_area[i].get_free_area_size()>=work.get_work_size()){
     
            if(free_area[i].get_free_area_size()>work.get_work_size()){
     //空闲区比作业大
                work.set_work_start_address(free_area[i].get_free_area_start_address());
                free_area[i].set_free_area_size(free_area[i].get_free_area_size()-work.get_work_size());
                free_area[i].set_free_area_start_address(free_area[i].get_free_area_start_address() + work.get_work_size());
                for (int j = 0; j < bcount;j++)
                    if(block[j].get_name()==free_area[i].get_free_area_name()){
     
                        block[j].set_start_address(free_area[i].get_free_area_start_address());
                        block[j].set_size(free_area[i].get_free_area_size());
                    }
                addblock_work(work);
                flag = true;
                break;
            }
            else{
     //空闲区大小和作业相等   
                for (int j = 0; j < bcount;j++)
                    if(block[j].get_name()==free_area[i].get_free_area_name())
                        block[j].set_name(work.get_work_name());
                block[bcount].set_name(work.get_work_name());
                for (int j = i; j < fcount-1; j++){
     
                    free_area[j].set_free_area_size(free_area[j + 1].get_free_area_size());
                    free_area[j].set_free_area_start_address(free_area[j + 1].get_free_area_start_address());
                    free_area[j].set_free_area_name(free_area[j + 1].get_free_area_name());
                }
                free_area[fcount-1].set_state("empty");
                fcount--;
                work.set_work_start_address(free_area[i].get_free_area_start_address());
                flag = true;
                break;
            }
        }
        else
            flag = false;
    }
    if(flag){
     //分配成功则打印空闲区说明表和主存空间分配情况
        show_free_area(free_area);
        show_Occupation();
    }
    else
       cout << "Allocating failed!" << endl; 
}

void recover(Work &work, Free_area *free_area){
     //回收算法
    for (int i = 0; i < fcount; i++){
     
        if(free_area[i].get_free_area_start_address()>work.get_work_start_address()){
     
            if((work.get_work_start_address()==free_area[i-1].get_free_area_start_address()+free_area[i-1].get_free_area_size())&&(work.get_work_start_address()+work.get_work_size()<free_area[i].get_free_area_start_address())){
     
                //释放区下邻空闲区
                free_area[i - 1].set_free_area_size(free_area[i - 1].get_free_area_size() + work.get_work_size());
                deleteblock_work(work);
                for (int j = 0; j < bcount; j++)
                    if(block[j].get_name()==free_area[i-1].get_free_area_name())
                        block[j].set_size(free_area[i - 1].get_free_area_size());
                break;
            }
            else if((i==0||(free_area[i-1].get_free_area_start_address()+free_area[i-1].get_free_area_size()<work.get_work_start_address()))&&work.get_work_start_address()+work.get_work_size()==free_area[i].get_free_area_start_address()){
        
                //释放区上邻空闲区
                free_area[i].set_free_area_size(free_area[i].get_free_area_size()+work.get_work_size());
                free_area[i].set_free_area_start_address(work.get_work_start_address());
                deleteblock_work(work);
                for (int j = 0; j < bcount; j++)
                    if(block[j].get_name()==free_area[i].get_free_area_name()){
     
                        block[j].set_size(free_area[i].get_free_area_size());
                        block[j].set_start_address(free_area[i].get_free_area_start_address());
                    }
                break;
            }
            else if((free_area[i-1].get_free_area_start_address()+free_area[i-1].get_free_area_size()==work.get_work_start_address())&&(work.get_work_start_address()+work.get_work_size()==free_area[i].get_free_area_start_address())){
     
                //释放区上下都与空闲区邻接
                free_area[i-1].set_free_area_size(free_area[i-1].get_free_area_size()+work.get_work_size()+free_area[i].get_free_area_size());
                deleteblock_work(work);
                deleteblock_free_area(free_area[i]);
                for (int j = i; j < fcount; j++){
     
                    free_area[j].set_free_area_size(free_area[j+1].get_free_area_size());
                    free_area[j].set_free_area_start_address(free_area[j+1].get_free_area_start_address());
                    free_area[j].set_free_area_name(free_area[j+1].get_free_area_name());
                    free_area[j].set_state(free_area[j + 1].get_state());
                }
                for (int j = 0; j < bcount; j++)
                    if(block[j].get_name()==free_area[i-1].get_free_area_name())
                        block[j].set_size(free_area[i - 1].get_free_area_size());
                break;
            }
            else if((i==0||(free_area[i-1].get_free_area_start_address()+free_area[i-1].get_free_area_size()<work.get_work_start_address()))&&work.get_work_start_address()+work.get_work_size()<free_area[i].get_free_area_start_address()){
     
                //释放区与空闲区不邻接
                for (int j = fcount-1; j >= i; j--){
     
                    free_area[j+1].set_free_area_size(free_area[j].get_free_area_size());
                    free_area[j+1].set_free_area_start_address(free_area[j].get_free_area_start_address());
                    free_area[j+1].set_free_area_name(free_area[j].get_free_area_name());
                    free_area[j+1].set_state(free_area[j].get_state());
                }
                free_area[i].set_free_area_name("free_area");
                free_area[i].set_free_area_size(work.get_work_size());
                free_area[i].set_free_area_start_address(work.get_work_start_address());
                fcount++;
                for (int j = 0; j < bcount; j++)
                    if(block[j].get_name()==work.get_work_name())
                        block[j].set_name(free_area[i].get_free_area_name());
                break;
            } 
        }
    }
    show_free_area(free_area);
    show_Occupation();
}

int main(){
     
    block[0].set_name("OS"); block[0].set_start_address(0); block[0].set_size(10); bcount++;
    Free_area free_area[N]={
     Free_area("free_area1", 45, 20), Free_area("free_area2", 110, 146)};
    cout << "Initial free area description table:" << endl;
    cout << setw(60) << setfill('-') << left << "-" <<endl;
    cout << setw(20) << setfill(' ') << left << "start_address" << setw(20) << setfill(' ') << left << "free_area_size"<< setw(20) << setfill(' ') << left << "state"<<endl;
    cout << setw(60) << setfill('-') << left << "-" <<endl;
    for (int i = 0; i < N; i++){
         
        if(free_area[i].get_state()!="empty"){
     
            fcount++;
            addblock_free_area(free_area[i]);
            cout << setw(20) << setfill(' ') << left << free_area[i].get_free_area_start_address() << setw(20) << setfill(' ') << left << free_area[i].get_free_area_size() << setw(20) << setfill(' ') << left << free_area[i].get_state() <<endl;
        }
        else
            cout << setw(40) << setfill(' ') << left <<" "<<setw(20) << setfill(' ') << left << free_area[i].get_state() << endl;
    }
    cout << setw(60) << setfill('-') << left << "-" <<endl;

    sort(free_area, free_area + fcount, cmp);
    //初始化作业信息
    Work work1("work1", 10); work1.set_work_start_address(10);addblock_work(work1);
    Work work4("work4", 25); work4.set_work_start_address(20);addblock_work(work4);
    Work work2("work2", 45); work2.set_work_start_address(65);addblock_work(work2);
    show_Occupation();
    Work work3("work3", 10);
    cout << endl;
    cout << "Allocating main memory for work3  (" <<work3.get_work_size()<<"KB)"<< endl;
    first_fit_assign(work3, free_area);//分配work3
    cout << endl;
    cout << "Recovery main memory from work2" << endl;
    recover(work2, free_area);//回收work2
    cout << endl;
    cout << "Recovery main memory from work4" << endl;
    recover(work4, free_area);//回收work4
    cout << endl;
    cout << "Recovery main memory from work3" << endl;
    recover(work3, free_area);//回收work3
    return 0;
}

主存分配回收算法(BF、FF)用C++实现_第6张图片
主存分配回收算法(BF、FF)用C++实现_第7张图片
主存分配回收算法(BF、FF)用C++实现_第8张图片
主存分配回收算法(BF、FF)用C++实现_第9张图片
主存分配回收算法(BF、FF)用C++实现_第10张图片

2.最佳适应算法

#include 
#include 
#include 
#include
#define N 10//空闲区说明表的大小
using namespace std;
int fcount = 0;//未分配的空闲区数量
int bcount = 0;//主存空间占用数

class Block{
     //主存空间的每一个块表示OS/作业/空闲区
    public:    
        string get_name(){
     return name;}
        int get_start_address(){
     return start_address;}
        int get_size(){
     return size;}
        void set_name(string s) {
      name = s; }
        void set_size(int s) {
      size = s; }
        void set_start_address(int s) {
      start_address = s; }    
    private:
        string name;        //每一个块的名字
        int start_address;  //每一个块的起始地址
        int size;           //每一个块的大小
};
class Work: public Block{
     //作业类,从block类继承
    public:
        Work() {
      set_start_address(0); }
        Work(string n, int s){
     //初始化
            set_name(n);
            set_size(s);
            set_start_address(0);
        }
        int get_work_size(){
      return get_size();}
        string get_work_name(){
     return get_name();}
        int get_work_start_address(){
     return get_start_address();}
        void set_work_start_address(int n) {
      set_start_address(n); }
};

Block block[10];//定义一个展示主存空间的数组

class Free_area:public Block{
     //空闲区类,继承于block类
    public:
        Free_area() {
     state = "empty";};
        Free_area(string n, int s1, int s2) {
     //初始化
            set_name(n);
            set_start_address(s1);
            set_size(s2);
            state = "unappropriated";
        }
        string get_free_area_name(){
     return get_name();}
        int get_free_area_start_address(){
     return get_start_address();}
        int get_free_area_size(){
     return get_size();}
        string get_state(){
     return state;}
        void set_free_area_name(string s) {
      set_name(s); }
        void set_free_area_size(int s) {
      set_size(s); }
        void set_free_area_start_address(int s) {
      set_start_address(s); }
        void set_state(string s) {
      state = s; }
    private:
        string state;//空闲区的状态,为未分配或空表目
};

bool cmp1(Block a, Block b){
     //sort函数的比较条件,按照起始地址排序
    return a.get_start_address()<b.get_start_address();
}

bool cmp2(Free_area a, Free_area b){
     //sort函数的比较条件,按照大小排序
    return a.get_free_area_size()<b.get_free_area_size();
}

void addblock_work(Work work){
     //往主存空间中加入作业
    block[bcount].set_name(work.get_work_name());
    block[bcount].set_start_address(work.get_work_start_address());
    block[bcount].set_size(work.get_work_size());
    bcount++;
}

void deleteblock_work(Work work){
     //从主存空间中删除作业
    for (int i = 0; i < bcount; i++)
        if(block[i].get_name()==work.get_work_name())
            for (int j = i; j < bcount-1; j++){
     
                block[j].set_name(block[j + 1].get_name());
                block[j].set_size(block[j + 1].get_size());
                block[j].set_start_address(block[j + 1].get_start_address());
            }
    bcount--;
}

void addblock_free_area(Free_area free_area){
     //往主存空间中加入空闲区
    block[bcount].set_name(free_area.get_free_area_name());
    block[bcount].set_size(free_area.get_free_area_size());
    block[bcount].set_start_address(free_area.get_free_area_start_address());
    bcount++;
}

void deleteblock_free_area(Free_area free_area){
     //从主存空间中删除空闲区
    for (int i = 0; i < bcount; i++)
        if(block[i].get_name()==free_area.get_free_area_name())
            for (int j = i; j < bcount-1; j++){
     
                block[j].set_name(block[j + 1].get_name());
                block[j].set_size(block[j + 1].get_size());
                block[j].set_start_address(block[j + 1].get_start_address());
            }
    bcount--;
}

void show_free_area(Free_area *free_area){
     //打印出空闲区说明表
    cout << "Free area description table:" << endl;
    cout << setw(60) << setfill('-') << left << "-" <<endl;
    cout << setw(20) << setfill(' ') << left << "start_address" << setw(20) << setfill(' ') << left << "free_area_size"<< setw(20) << setfill(' ') << left << "state"<<endl;    
    cout << setw(60) << setfill('-') << left << "-" <<endl;
    for (int i = 0; i < N; i++){
         
        if(free_area[i].get_state()!="empty")
            cout << setw(20) << setfill(' ') << left << free_area[i].get_free_area_start_address() << setw(20) << setfill(' ') << left << free_area[i].get_free_area_size() << setw(20) << setfill(' ') << left << free_area[i].get_state() <<endl;
        else
            cout << setw(40) << setfill(' ') << left <<" "<<setw(20) << setfill(' ') << left << free_area[i].get_state() << endl;
    }
    cout << setw(60) << setfill('-') << left << "-" <<endl;
}

void show_Occupation(){
     //打印出主存空间占用情况
    sort(block, block + bcount, cmp1);
    cout << "Occupation of main memory space:" << endl;
    for (int i = 0; i < bcount; i++){
     
        cout << "      ---------------------" <<endl;
        cout << setw(5) << setfill(' ') << right << block[i].get_start_address() << "K"<< "| " << setw(10) << setfill(' ') << right <<block[i].get_name() << "(" << setw(3) << setfill(' ') << left <<block[i].get_size() << "KB) |  " << endl;
    }
    cout << "  256K---------------------" <<endl;
}

void best_fit_assign(Work &work, Free_area *free_area){
     //首最佳适应算法实现作业的分配
    bool flag;//表示作业是否分配成功
    sort(free_area, free_area + fcount, cmp2);
    for (int i = 0; i < fcount; i++){
     
        if(free_area[i].get_free_area_size()>=work.get_work_size()){
     
            if(free_area[i].get_free_area_size()>work.get_work_size()){
     //空闲区比作业大
                work.set_work_start_address(free_area[i].get_free_area_start_address());
                free_area[i].set_free_area_size(free_area[i].get_free_area_size()-work.get_work_size());
                free_area[i].set_free_area_start_address(free_area[i].get_free_area_start_address() + work.get_work_size());
                for (int j = 0; j < bcount;j++)
                    if(block[j].get_name()==free_area[i].get_free_area_name()){
     
                        block[j].set_start_address(free_area[i].get_free_area_start_address());
                        block[j].set_size(free_area[i].get_free_area_size());
                    }
                addblock_work(work);
                flag = true;
                break;
            }
            else{
     //空闲区大小和作业相等   
                for (int j = 0; j < bcount;j++)
                    if(block[j].get_name()==free_area[i].get_free_area_name())
                        block[j].set_name(work.get_work_name());
                block[bcount].set_name(work.get_work_name());
                for (int j = i; j < fcount-1; j++){
     
                    free_area[j].set_free_area_size(free_area[j + 1].get_free_area_size());
                    free_area[j].set_free_area_start_address(free_area[j + 1].get_free_area_start_address());
                    free_area[j].set_free_area_name(free_area[j + 1].get_free_area_name());
                }
                free_area[fcount-1].set_state("empty");
                fcount--;
                work.set_work_start_address(free_area[i].get_free_area_start_address());
                flag = true;
                break;
            }
        }
        else
            flag = false;
    }
    if(flag){
     //分配成功则打印空闲区说明表和主存空间分配情况
        show_free_area(free_area);
        show_Occupation();
    }
    else
       cout << "Allocating failed!" << endl; 
}

void recover(Work &work, Free_area *free_area){
     //回收算法
    sort(free_area, free_area + fcount, cmp1);
    for (int i = 0; i < fcount; i++){
     
        if(free_area[i].get_free_area_start_address()>work.get_work_start_address()){
     
            if((work.get_work_start_address()==free_area[i-1].get_free_area_start_address()+free_area[i-1].get_free_area_size())&&(work.get_work_start_address()+work.get_work_size()<free_area[i].get_free_area_start_address())){
     
                //释放区下邻空闲区
                free_area[i - 1].set_free_area_size(free_area[i - 1].get_free_area_size() + work.get_work_size());
                deleteblock_work(work);
                for (int j = 0; j < bcount; j++)
                    if(block[j].get_name()==free_area[i-1].get_free_area_name())
                        block[j].set_size(free_area[i - 1].get_free_area_size());
                break;
            }
            else if((i==0||(free_area[i-1].get_free_area_start_address()+free_area[i-1].get_free_area_size()<work.get_work_start_address()))&&work.get_work_start_address()+work.get_work_size()==free_area[i].get_free_area_start_address()){
        
                //释放区上邻空闲区
                free_area[i].set_free_area_size(free_area[i].get_free_area_size()+work.get_work_size());
                free_area[i].set_free_area_start_address(work.get_work_start_address());
                deleteblock_work(work);
                for (int j = 0; j < bcount; j++)
                    if(block[j].get_name()==free_area[i].get_free_area_name()){
     
                        block[j].set_size(free_area[i].get_free_area_size());
                        block[j].set_start_address(free_area[i].get_free_area_start_address());
                    }
                break;
            }
            else if((free_area[i-1].get_free_area_start_address()+free_area[i-1].get_free_area_size()==work.get_work_start_address())&&(work.get_work_start_address()+work.get_work_size()==free_area[i].get_free_area_start_address())){
     
                //释放区上下都与空闲区邻接
                free_area[i-1].set_free_area_size(free_area[i-1].get_free_area_size()+work.get_work_size()+free_area[i].get_free_area_size());
                deleteblock_work(work);
                deleteblock_free_area(free_area[i]);
                for (int j = i; j < fcount; j++){
     
                    free_area[j].set_free_area_size(free_area[j+1].get_free_area_size());
                    free_area[j].set_free_area_start_address(free_area[j+1].get_free_area_start_address());
                    free_area[j].set_free_area_name(free_area[j+1].get_free_area_name());
                    free_area[j].set_state(free_area[j + 1].get_state());
                }
                for (int j = 0; j < bcount; j++)
                    if(block[j].get_name()==free_area[i-1].get_free_area_name())
                        block[j].set_size(free_area[i - 1].get_free_area_size());
                break;
            }
            else if((i==0||(free_area[i-1].get_free_area_start_address()+free_area[i-1].get_free_area_size()<work.get_work_start_address()))&&work.get_work_start_address()+work.get_work_size()<free_area[i].get_free_area_start_address()){
     
                //释放区与空闲区不邻接
                for (int j = fcount-1; j >= i; j--){
     
                    free_area[j+1].set_free_area_size(free_area[j].get_free_area_size());
                    free_area[j+1].set_free_area_start_address(free_area[j].get_free_area_start_address());
                    free_area[j+1].set_free_area_name(free_area[j].get_free_area_name());
                    free_area[j+1].set_state(free_area[j].get_state());
                }
                free_area[i].set_free_area_name("free_area");
                free_area[i].set_free_area_size(work.get_work_size());
                free_area[i].set_free_area_start_address(work.get_work_start_address());
                fcount++;
                for (int j = 0; j < bcount; j++)
                    if(block[j].get_name()==work.get_work_name())
                        block[j].set_name(free_area[i].get_free_area_name());
                break;
            } 
        }
    }
    show_free_area(free_area);
    show_Occupation();
}

int main(){
     
    block[0].set_name("OS"); block[0].set_start_address(0); block[0].set_size(10); bcount++;
    Free_area free_area[N]={
     Free_area("free_area1", 20, 50), Free_area("free_area2", 10, 10), Free_area("free_area3", 80, 30), Free_area("free_area4", 135, 121)};
    cout << "Initial free area description table:" << endl;
    cout << setw(60) << setfill('-') << left << "-" <<endl;
    cout << setw(20) << setfill(' ') << left << "start_address" << setw(20) << setfill(' ') << left << "free_area_size"<< setw(20) << setfill(' ') << left << "state"<<endl;
    cout << setw(60) << setfill('-') << left << "-" <<endl;
    for (int i = 0; i < N; i++){
         
        if(free_area[i].get_state()!="empty"){
     
            fcount++;
            addblock_free_area(free_area[i]);
            cout << setw(20) << setfill(' ') << left << free_area[i].get_free_area_start_address() << setw(20) << setfill(' ') << left << free_area[i].get_free_area_size() << setw(20) << setfill(' ') << left << free_area[i].get_state() <<endl;
        }
        else
            cout << setw(40) << setfill(' ') << left <<" "<<setw(20) << setfill(' ') << left << free_area[i].get_state() << endl;
    }
    cout << setw(60) << setfill('-') << left << "-" <<endl;

    sort(free_area, free_area + fcount, cmp2);
    //初始化作业信息
    Work work1("work1", 10); work1.set_work_start_address(70);addblock_work(work1);
    Work work4("work4", 25); work4.set_work_start_address(110);addblock_work(work4);
    //Work work2("work2", 45); work2.set_work_start_address(65);addblock_work(work2);
    show_Occupation();
    Work work3("work3", 20);
    cout << endl;
    cout << "Allocating main memory for work3  (" <<work3.get_work_size()<<"KB)"<< endl;
    best_fit_assign(work3, free_area);//分配work3
    Work work2("work2", 10);
    cout << endl;
    cout << "Allocating main memory for work2  (" <<work2.get_work_size()<<"KB)"<< endl;
    best_fit_assign(work2, free_area);//分配work2
    cout << endl;
    cout << "Recovery main memory from work1" << endl;
    recover(work1, free_area);//回收work1
    cout << endl;
    cout << "Recovery main memory from work3" << endl;
    recover(work3, free_area);//回收work3
    return 0;
}

主存分配回收算法(BF、FF)用C++实现_第11张图片
主存分配回收算法(BF、FF)用C++实现_第12张图片
主存分配回收算法(BF、FF)用C++实现_第13张图片
主存分配回收算法(BF、FF)用C++实现_第14张图片
主存分配回收算法(BF、FF)用C++实现_第15张图片

四、小结与讨论

1.首次适应算法倾向于倾向于优先利用内存中低址部分的空闲分区,从而保留了高址部分的大空闲区。这为以后到达的大作业分配大的内存空间创造了条件。其缺点是低址部分不断被划分,会留下许多难以利用的、很小的空闲分区,称为碎片。而每次查找又都是从低址部分开始的,这无疑又会增加查找可用空闲分区时的开销。

2.最佳适应算法是指每次为作业分配内存时,总是把能满足要求、又是最小的空闲分区分配给作业,避免大材小用。为了加速寻找,该算法要求将所有的空闲分区按其容量以从小到大的顺序形成一个空闲分区链。这样第一次找到的,能满足要求的空闲区必然是最佳的。孤立的看最佳适应算法似乎是最佳的,然而在宏观上却不一定。因为每次分配后所切割下来的剩余部分总是最小的,这样在存储器中会留下许多难以利用的碎片。

你可能感兴趣的:(笔记)