操作系统存储管理实验

该文提供了三种不同的内存管理方案:固定式分区分配,可变式分区分配(首次适应、循环首次适应、最佳适应算法),以及段页式存储管理的地址转换模拟。文中通过代码详细展示了如何分配和回收内存,以及如何进行地址转换。
摘要由CSDN通过智能技术生成

1.设计一个固定式分区分配(连续分配)的存储管理方案,并模拟实现分区的分配和回收过程。

可以假定每个作业都是批处理作业,并且不允许动态申请内存。为实现分区的分配和回收,可以设定一个分区说明表,按照表中的有关信息进行分配,并根据分区的分配和回收情况修改该表。

                                                        分区说明表

分区号

大小(KB)

始址(KB)

状态

1

25

16

已分配

2

38

40

已分配

3

57

110

未分配

 

#include<iostream>
#include<cstring>
#include<random>
#include<iomanip>
#define StarAddress 0
#define N 9
using namespace std;
struct node
{
    string name; //名称
    int num; //内存大小
    int realnum; //真实所占
    int address; //起始地址
    int state; //标志
};
node List[N]; //节点数组
int NUM[N] { 24, 39, 55, 63, 81, 128, 150, 169, 188 };
int main()
{
    int n = 0;
    for (int i = 0; i < N; i++)
    {
        List[i].name = "NULL";
        List[i].num = NUM[i];
        List[i].realnum = NUM[i];
        List[i].state = 0;
        if (i == 0)List[i].address = StarAddress;
        else List[i].address = List[i - 1].num + List[i - 1].address;
    }
    while (1)
    {
        cout << "=================================================" << endl;
        cout << " 1、内存分配 " << endl;
        cout << " 2、回收分配内存 " << endl;
        cout << " 3、显示当前内存分配 " << endl;
        cout << " 4、退出 " << endl;
        cout << "=================================================" << endl;
        cin >> n; //输入需要的操作对应的数字
        switch (n)
        {
        case 1:
        {
            bool flag = 0;
            cout << "输入进程名称\n";
            string name;
            cin >> name;
            cout << "进程所占空间大小\n";
            int num;
            cin >> num;
            for (int i = 0; i < N; i++)
            {
                if (List[i].state == 0 && List[i].num >= num)
                {
                    List[i].name = name;
                    List[i].num = num;
                    List[i].state = 1; //修改状态
                    flag = 1;
                }
                if (flag)break;
            }
            if (!flag)cout << "所占空间超出上限!\n";
            break;
        }
        case 2:
        {
            cout << "输入要删除的进程名称\n";
            string k; //名称
            cin >> k;
            for (int i = 0; i < N; i++)
            {
                List[i].name = "NULL";
                List[i].num = List[i].realnum;
            }
            break;
        }
        case 3:
        {
            cout << "区号 名称 起始地址 大小 状态\n";
            for (int i = 0; i < N; i++)
            {
                if (List[i].state != 0)
                {
                    cout << i+1<<setw(12) << List[i].name << setw(18) << List[i].address <<
                         setw(15) << List[i].num << setw(20) << "已分配\n";
                }
                else cout << i+1<<setw(15) << setw(30) << List[i].address << setw(15) <<
                              List[i].num << setw(20) << "未分配\n";
            }
            break;
        }
        case 4:
        {
            return 0;
            break;
        }
        default:
        {
            cout << "输入有误请重新输入\n";
            break;
        }
        }
    }
    return 0;
}

2.设计一个可变式分区分配的存储管理方案。并模拟实现分区的分配和回收过程。

对分区的管理法可以是下面三种算法之一:

首次适应算法

循环首次适应算法

最佳适应算法

空闲分区表

序号

分区大小(KB )

分区始址(KB)

状态

1

64

44

可用

2

24

132

可用

3

40

210

可用

4

30

270

可用

5

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100; //最大分区数量和最大作业数量
int pcs_num; //process_num进程数量
int ptt_num; //partition_num分区数量
struct PTT
{
    int id; //分区编号
    int size; //分区大小
    int remain; //剩余大小
};
PTT ptt[N]; //partition 每一块分区的大小
int pcs[N]; //process 每一个作业的大小
int pcs_alcs[N]; //process_allocation 作业的分配情况
//排序规则1:以剩余大小优先,分区编号其次,升序
bool cmp1(PTT a, PTT b)
{
    if (a.remain != b.remain) return a.remain < b.remain;
    else return a.id < b.id;
}
//排序规则2:以剩余大小优先,分区编号其次,降序
bool cmp2(PTT a, PTT b)
{
    if (a.remain != b.remain) return a.remain > b.remain;
    else return a.id > b.id;
}
//排序规则3:按分区编号排序
bool cmp3(PTT a, PTT b)
{
    return a.id < b.id;
}
void print_ptt()   //输出当前分区大小情况
{
    PTT backup[N];
    memcpy(backup, ptt, sizeof ptt); //备份
    sort(ptt + 1, ptt + ptt_num + 1, cmp3); //对分区进行排序
    cout << endl;
    cout << "********************当前分区大小情况********************" << endl;
    cout << "分区序号\t";
    for (int i = 1; i <= ptt_num; i++)
        cout << "分区" << ptt[i].id << '\t';
    cout << endl;
    cout << "分区大小\t";
    for (int i = 1; i <= ptt_num; i++)
        cout << ptt[i].size << '\t';
    cout << endl;
    cout << "剩余大小\t";
    for (int i = 1; i <= ptt_num; i++)
        cout << ptt[i].remain << '\t';
    cout << endl;
    cout << "********************************************************" << endl;
    cout << endl;
    memcpy(ptt, backup, sizeof ptt); //恢复
}
void print_pcs()
{
    cout << endl;
    cout << "********************当前作业分配情况********************" << endl;
    cout << "作业名称" << '\t';
    for (int i = 1; i <= pcs_num; i++)
        cout << "作业" << char('A' + i - 1) << " " << '\t';
    cout << endl;
    cout << "作业分配" << '\t';
    for (int i = 1; i <= pcs_num; i++)
        if (pcs_alcs[i] == 0) cout << "未分配 " << '\t';
        else cout << "空闲区" << pcs_alcs[i] << '\t';
    cout << endl;
    cout << "******************************************************" << endl;
    cout << endl;
}
void print_all()
{
    print_ptt(); //输出分区大小情况
    print_pcs(); //输出分配情况
}
bool first_fit()
{
//首次适应算法
    bool flag = true;
//初始化分配情况
    memset(pcs_alcs, 0, sizeof pcs_alcs);
    PTT backup[N];
    memcpy(backup, ptt, sizeof ptt); //备份
//顺序遍历分区,分区容量大与作业所需就分配
    for (int i = 1; i <= pcs_num; i++)
    {
        int j;
        for (j = 1; j <= ptt_num; j++)
        {
            if (pcs[i] <= ptt[j].remain)
            {
//作业小于分区剩余
                pcs_alcs[i] = ptt[j].id; //进行分配
                ptt[j].remain -= pcs[i];
                break;
            }
        }
        if (j > ptt_num)
            flag = false; //有未分配返回false
    }
    print_all();
    memcpy(ptt, backup, sizeof ptt); //恢复
    return flag;
}
int main()
{
    cout << "请输入分区数量" << endl;
    cin >> ptt_num;
    cout << "请输入每一块分区的大小" << endl;
    for (int i = 1; i <= ptt_num; i++)
    {
        ptt[i].id = i;
        cin >> ptt[i].size;
        ptt[i].remain = ptt[i].size;
    }
    cout << "请输入作业数量" << endl;
    cin >> pcs_num;
    cout << "请输入每一个作业的大小" << endl;
    for (int i = 1; i <= pcs_num; i++)
        cin >> pcs[i];
    print_ptt(); //输出分区大小情况
    print_pcs(); //输出分配情况
    cout << endl;
    cout << "首次适应算法" << endl;
    cout << endl;
    bool f1 = first_fit();
    return 0;
}

 

3、编写并调试一个段页式存储管理的地址转换的模拟程序。

  首先设计好段表、页表,然后给出若干个有一定代表性的地址,通过查找段表页表后得到转换的地址。

        要求打印转换前的地址,相应的段表,页表条款及转换后的地址,以便检查。

 

#include <iostream>
#include <cstring>
#define Maxn 5
using namespace std;
int pageTable[5] = { 2,3,6,8,9 };
int segAddress[5] = { 2,12,30,45,73 };
bool pageStatement[10];
int address[100];
int tranAddress[100];
int num;
int reigister[2];
typedef struct
{
    int seg_address;
    int seg_final_address;
} Box;
typedef struct
{
    Box data[Maxn];
} Segment;
Segment seg_table;
void Seg_table()
{
    reigister[0] = segAddress[0];
    reigister[1] = Maxn;
    memset(pageStatement, false, sizeof(pageStatement));
    for (int i = 0; i < 5; i++)
    {
        seg_table.data[i].seg_address = segAddress[i];
        seg_table.data[i].seg_final_address = pageTable[4] + segAddress[i] - reigister[0];
        pageStatement[pageTable[i]] = true;
        cout << seg_table.data[i].seg_address << " " << seg_table.data[i].seg_final_address << endl;
    }
}
void init()
{
    cout << "输入地址的个数:" << endl;
    cin >> num;
    cout << "输入地址" << endl;
    for (int i = 0; i < num; i++)
        cin >> address[i];
    Seg_table();
}
void addressTranslat()
{
    init();
    for (int k = 0; k < num; k++)
    {
        for (int i = 0; i < Maxn; i++)
        {
            if ((address[k] >= seg_table.data[i].seg_address) && (address[k] <= seg_table.data[i].seg_final_address))
            {
                int index = 0;
                for (int j = 0; j < 5; j++)
                {
                    if (seg_table.data[i].seg_address + pageTable[j] - reigister[0] == address[k]
                            && pageStatement[pageTable[j]] == true)
                    {
                        cout << address[k] << " 的地址转换:";
                        cout << "段号:" << i << " 段地址:"
                             << segAddress[i] << " 页号:" << j
                             << " 块号:" << pageTable[j] << endl;
                        pageStatement[pageTable[j]] = false;
                        index = 1;
                        i = Maxn;
                    }
                }
                if (index == 0)
                {
                    cout << "在页表未找到 " << address[k] << endl;
                    i = Maxn;
                }
            }
            else if (address[k] < reigister[0])
            {
                cout << "地址 " << address[k] << " 太小" << endl;
                i = Maxn;
            }
            else if (address[k] > seg_table.data[Maxn - 1].seg_final_address)
            {
                cout << "地址 " << address[k] << " 太大超出" << endl;
                i = Maxn;
            }
            else
            {
                if (i == Maxn - 1)
                    cout << "在段表未找到 " << address[k] << endl;
            }
        }
    }
}
int main()
{
    addressTranslat();
    return 0;
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南城`烟雨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值