分页存储管理模拟

该博客介绍了一个操作系统实验,实现了内存管理的基本功能,包括内存分配、回收、显示内存状态和访问内存。通过结构体表示内存段和作业,模拟内存分配策略,处理作业申请、释放内存,并能检查内存访问是否越界。实验提供了具体的操作流程和测试数据,有助于理解内存管理原理。
摘要由CSDN通过智能技术生成

操作系统实验


任务

• 初始化内存大小为100000字节
• 每个页框占1000个字节
• 则一共有100个页框(假设默认页框号为0-99号)。
• 功能键:

  • 0 退出
  • 1 为作业分配内存
  • 输入:作业名、作业所占字节数
  • 执行逻辑:根据作业所需字节数计算作业所需页面数
  • 若内存容量不够,则应提示无法为作业分配内存
  • 若内存容量够用,则选择空闲页面装载作业,并在作业页表进行登记
  • 2 回收作业内存
  • 输入:作业名
  • 执行逻辑:查找页表,找到输入作业名所占用的页框,并回收。
  • 3 显示内存分配情况
    • 已分配内存空间情况(作业名,起始地址, 占用页框号)和空闲区情况(起始地址,长度)
    • 根据进程展示内存分配情况
    • 显示每一个进程所占用的页框号(按照进程顺序)
    • 根据内存真实情况
    • 显示内存每一个页框号被哪个进程占用,(按照页框顺序)
  • 4 访问

• 输入: 作业名 、逻辑访问地址(字节偏移)
• 执行逻辑:根据给定的作业名和逻辑访问地址计算物理地址(几号页框),若越界访问,则给出错误提示。否则给出逻辑访问地址对应的物理访问地址。

测试数据

  • (1 a 5000)
  • (1 b 38400)
  • (1 c 49700)
  • (1 d 11000) 提示内存不够
  • (2 b)
  • (1 d 25000)
  • (1 e 16000)
  • (2 a)
  • (1 f 10000) 提示内存不够
  • (4 e 15437) 显示95号页框 437偏移(也可直接换算成物理地址,以字节为单位)
  • (4 c 50000) 提示访问越界
  • (3) 内存分配情况如下(按进程显示):
    作业名 占用页面数 占用页框号
    d 25 5-29
    e 16 30-43 94-95
    c 50 44-93

代码

结构体

描述内存段

struct work_paragraph
{
	int start;
	int end;
};

描述作业

struct work
{
	string name;
	vector<work_paragraph> work_place;//页框段
	int size;//长度
	int place_num;//页框总数
};
vector<work> works;//总的作业
vector<work_paragraph>  place;//总的内存段
int surplus = 100;//剩余的内存数

1分配内存

设置一个可以将place空间从大到小排序插入的函数

void add(vector<work_paragraph> w, vector<work_paragraph>&  place)
{//将place按大小顺序添加;
	int j = 0;
	int max = place.back().start;//记录当前内存利用段的最大值
	for (int i = 0; i < w.size(); i++)
	{
		int num = place.size();
		if (w[i].end > max)
		{
			place.push_back(w[i]);
		}
		else
		{
			for (; j < num; j++)
			{//当片段以利用的内存范围内时
				if (w[i].end < place[j].start)
				{//当w的片段在j指向的片段前面时
					place.insert(place.begin() + j, w[i]);//将该数插入
					j++;
					break;
				}
			}
		}
	}
}

其中ceil函数是向上取整函数,要注意其实和结束位置1的情况

int create(vector<work_paragraph>&  place, vector<work>& works,int surplus)
{
	work w;
	work_paragraph gr;
	int start_temp=0, end_temp=0;
	cout << "请输入作业名" << endl;
	cin >>w.name;
	cout << "请输入作业所占字节数" << endl;
	cin >> w.size;
	int sum_num = ceil(w.size / 1000);
	w.place_num = sum_num;//向上取整
	if (surplus < w.place_num)
	{
		cout << "内存不足,申请失败" << endl;
		return surplus;
	}
	if (place.empty() == true)
	{//当当前总内存内没有存内容时
		gr.start = 0;
		gr.end = sum_num-1;
		place.push_back(gr);
		w.work_place.push_back(gr);
		surplus -= w.place_num;
		works.push_back(w);
		cout << "作业内存申请成功" << endl;
		return surplus;
	}
	for (int i = 0; i < place.size(); i++)
	{
		end_temp = place[i].start-1;
		if (start_temp < end_temp)
		{//如果再place的使用片段中有空隙时
			if (end_temp - start_temp < sum_num)
			{
				//当前片段不能满足作业
				gr.start = start_temp;
				gr.end = end_temp;
				w.work_place.push_back(gr);//将该片段加入作业量中
				sum_num = sum_num - end_temp + start_temp-1;
			}
			else
			{
				//当前片段能够满足作业了
				gr.start = start_temp;
				gr.end = start_temp + sum_num-1;
				w.work_place.push_back(gr);
				add(w.work_place,place);//按顺序将内存占用空间加入palce
				surplus -= w.place_num;//将剩余量修改
				works.push_back(w);//将改作业加入作业组中
				cout << "作业内存申请成功" << endl;
				return surplus;//结束循环
			}
		}
		start_temp = place[i].end+1;
	}
	//当循环没有结束,则是没有找到足够满足当前作业的空隙,所以在后面增加
	gr.start = place.back().end + 1;
	gr.end = gr.start + sum_num - 1;
	w.work_place.push_back(gr);
	add(w.work_place, place);
	surplus -= w.place_num;
	works.push_back(w);
	cout << "作业内存申请成功" << endl;
	return surplus;
}

2回收作业

其实也可以使用remove函数去实现将place中的内存移走,但需要重载“==”

int  reclaim(vector<work_paragraph>& place, vector<work>& works, int surplus)
{
	work w;
	cout << "请输入作业名" << endl;
	cin >> w.name;
	for (int i = 0; i < works.size(); i++)
	{
		if (works[i].name == w.name)
		{
			w = works[i];
			//找到了作业名
			int address = 0;
			for (int j = 0; j < w.work_place.size(); j++)
			{
				while (true)
				{
					if (place[address].start==w.work_place[j].start&&place[address].end==w.work_place[j].end)
					{
						place.erase(place.begin() + address);
						break;
					}
					address++;
				}
			}
			works.erase(works.begin()+i);//删除作业列表中的元素;
			surplus += w.place_num;
			return surplus;
		}
	}
	//没有找到作业
	cout << "没有找到该作业" << endl;
	return surplus;
}

3显示内存

void show(vector<work_paragraph>& place, vector<work>& works, int surplus)
{
	cout << "内存分配情况如下:" << endl;
	if (works.size() == 0)
	{
		cout << "目前没有作业占用内存" << endl;
		return;
	}
	else
	{
		cout << "作业名称  " << "占用页框数  " << "占用页框号 " << endl;
		for (int i = 0; i < works.size(); i++)
		{
			cout << works[i].name << "     ";
			cout << works[i].place_num << "    ";
			for (int j = 0; j < works[i].work_place.size(); j++)
			{
				cout << works[i].work_place[j].start << "-" << works[i].work_place[j].end << "  ";
			}
			cout << endl;
		}
		cout << surplus << endl;
	}
}

4内存访问

void visit(vector<work_paragraph>& place, vector<work>& works, int surplus)
{
	work w;
	cout << "请输入你想要访问的作业名:" << endl;
	cin >> w.name;
	for (int i = 0; i < works.size(); i++)
	{
		if (works[i].name == w.name)
		{
			w = works[i];
			//找到了作业名
			int path;
			cout << "请输入逻辑访问地址:" << endl;
			cin >> path;
			if (path > w.size)
			{
				cout << "访问越界!!!" << endl;
				return;
			}
			int path_num = ceil(path / 1000);//向上取整
			int offset_path = path % 1000;//偏移量
			for (int j = 0; j < w.work_place.size(); j++)
			{
				int num = w.work_place[j].end - w.work_place[j].start;
				if (num < path_num)
				{//当前片段不包括访问页框
					path_num -= num;
				}
				else
				{//当前片段包括访问页框
					cout << "访问第" << w.work_place[j].start + path_num << "号页框";
					if (offset_path != 0)
					{
						cout << ",偏移量为:" << offset_path;
					}
					cout << endl;
					return;
				}
			}
			cout << "访问第" << w.work_place.back().start + path_num << "号页框";
			if (offset_path != 0)
			{
				cout << ",偏移量为:" << offset_path;
			}
			cout << endl;
			return;
		}
	}
	//没有找到作业
	cout << "没有找到该作业" << endl;
	return;
}

完整代码

#include<vector>
#include<ctime>
#include<random>
#include<cmath>
#include<iostream>
#include<string>
#include <math.h>

using namespace std;

struct work_paragraph
{
	int start;
	int end;
};

struct work
{
	string name;
	vector<work_paragraph> work_place;//页框段
	int size;//长度
	int place_num;//页框总数
};

void add(vector<work_paragraph> w, vector<work_paragraph>&  place)
{//将place按大小顺序添加;
	int j = 0;
	int max = place.back().start;//记录当前内存利用段的最大值
	for (int i = 0; i < w.size(); i++)
	{
		int num = place.size();
		if (w[i].end > max)
		{
			place.push_back(w[i]);
		}
		else
		{
			for (; j < num; j++)
			{//当片段以利用的内存范围内时
				if (w[i].end < place[j].start)
				{//当w的片段在j指向的片段前面时
					place.insert(place.begin() + j, w[i]);//将该数插入
					j++;
					break;
				}
			}
		}
	}
}

int create(vector<work_paragraph>&  place, vector<work>& works,int surplus)
{
	work w;
	work_paragraph gr;
	int start_temp=0, end_temp=0;
	cout << "请输入作业名" << endl;
	cin >>w.name;
	cout << "请输入作业所占字节数" << endl;
	cin >> w.size;
	int sum_num = ceil(w.size / 1000);
	w.place_num = sum_num;//向上取整
	if (surplus < w.place_num)
	{
		cout << "内存不足,申请失败" << endl;
		return surplus;
	}
	if (place.empty() == true)
	{//当当前总内存内没有存内容时
		gr.start = 0;
		gr.end = sum_num-1;
		place.push_back(gr);
		w.work_place.push_back(gr);
		surplus -= w.place_num;
		works.push_back(w);
		cout << "作业内存申请成功" << endl;
		return surplus;
	}
	for (int i = 0; i < place.size(); i++)
	{
		end_temp = place[i].start-1;
		if (start_temp < end_temp)
		{//如果再place的使用片段中有空隙时
			if (end_temp - start_temp < sum_num)
			{
				//当前片段不能满足作业
				gr.start = start_temp;
				gr.end = end_temp;
				w.work_place.push_back(gr);//将该片段加入作业量中
				sum_num = sum_num - end_temp + start_temp-1;
			}
			else
			{
				//当前片段能够满足作业了
				gr.start = start_temp;
				gr.end = start_temp + sum_num-1;
				w.work_place.push_back(gr);
				add(w.work_place,place);//按顺序将内存占用空间加入palce
				surplus -= w.place_num;//将剩余量修改
				works.push_back(w);//将改作业加入作业组中
				cout << "作业内存申请成功" << endl;
				return surplus;//结束循环
			}
		}
		start_temp = place[i].end+1;
	}
	//当循环没有结束,则是没有找到足够满足当前作业的空隙,所以在后面增加
	gr.start = place.back().end + 1;
	gr.end = gr.start + sum_num - 1;
	w.work_place.push_back(gr);
	add(w.work_place, place);
	surplus -= w.place_num;
	works.push_back(w);
	cout << "作业内存申请成功" << endl;
	return surplus;
}

int  reclaim(vector<work_paragraph>& place, vector<work>& works, int surplus)
{
	work w;
	cout << "请输入作业名" << endl;
	cin >> w.name;
	for (int i = 0; i < works.size(); i++)
	{
		if (works[i].name == w.name)
		{
			w = works[i];
			//找到了作业名
			int address = 0;
			for (int j = 0; j < w.work_place.size(); j++)
			{
				while (true)
				{
					if (place[address].start==w.work_place[j].start&&place[address].end==w.work_place[j].end)
					{
						place.erase(place.begin() + address);
						break;
					}
					address++;
				}
			}
			works.erase(works.begin()+i);//删除作业列表中的元素;
			surplus += w.place_num;
			return surplus;
		}
	}
	//没有找到作业
	cout << "没有找到该作业" << endl;
	return surplus;
}

void show(vector<work_paragraph>& place, vector<work>& works, int surplus)
{
	cout << "内存分配情况如下:" << endl;
	if (works.size() == 0)
	{
		cout << "目前没有作业占用内存" << endl;
		return;
	}
	else
	{
		cout << "作业名称  " << "占用页框数  " << "占用页框号 " << endl;
		for (int i = 0; i < works.size(); i++)
		{
			cout << works[i].name << "     ";
			cout << works[i].place_num << "    ";
			for (int j = 0; j < works[i].work_place.size(); j++)
			{
				cout << works[i].work_place[j].start << "-" << works[i].work_place[j].end << "  ";
			}
			cout << endl;
		}
		cout << surplus << endl;
	}
}

void visit(vector<work_paragraph>& place, vector<work>& works, int surplus)
{
	work w;
	cout << "请输入你想要访问的作业名:" << endl;
	cin >> w.name;
	for (int i = 0; i < works.size(); i++)
	{
		if (works[i].name == w.name)
		{
			w = works[i];
			//找到了作业名
			int path;
			cout << "请输入逻辑访问地址:" << endl;
			cin >> path;
			if (path > w.size)
			{
				cout << "访问越界!!!" << endl;
				return;
			}
			int path_num = ceil(path / 1000);//向上取整
			int offset_path = path % 1000;//偏移量
			for (int j = 0; j < w.work_place.size(); j++)
			{
				int num = w.work_place[j].end - w.work_place[j].start;
				if (num < path_num)
				{//当前片段不包括访问页框
					path_num -= num;
				}
				else
				{//当前片段包括访问页框
					cout << "访问第" << w.work_place[j].start + path_num << "号页框";
					if (offset_path != 0)
					{
						cout << ",偏移量为:" << offset_path;
					}
					cout << endl;
					return;
				}
			}
			cout << "访问第" << w.work_place.back().start + path_num << "号页框";
			if (offset_path != 0)
			{
				cout << ",偏移量为:" << offset_path;
			}
			cout << endl;
			return;
		}
	}
	//没有找到作业
	cout << "没有找到该作业" << endl;
	return;
}

void menu()
{
	cout << "1.分配内存\n"
		<< "2.回收内存\n"
		<< "3.显示内存分配\n"
		<< "4.访问内存\n"
		<< "0.退出" << endl;
	cout << "\n请选择:";
}

int main() {
	vector<work> works;//总的作业
	vector<work_paragraph>  place;//总的内存段
	int surplus = 100;//剩余的内存数
	int choose;
	menu();
	cin >> choose;
	while (choose != 0) {
		switch (choose) {
		case 1:
			surplus=create(place,works,surplus);
			break;
		case 2:
			surplus=reclaim(place, works, surplus);
			break;
		case 3:
			show(place, works, surplus);
			break;
		case 4:
			visit(place, works, surplus);
		default:
			break;
		}
		menu();
		cin >> choose;
	}
}
  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值