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; }