其他分享
首页 > 其他分享> > 2021-06-03

2021-06-03

作者:互联网

实验–主存空间的分配与回收

一、实验目的

  1. 熟悉主存的分配与回收。理解在不同的存储管理方式下,如何实现主存空间的分配与回收。
  2. 掌握动态分区分配方式中的数据结构和分配算法及动态分区存储管理方式及其实现过程。

二、实验任务

  1. 补充完整程序内的两个函数;
  2. 将程序在VC里编译链接后,自行编写测试文件,进行执行。

三、实验内容

//主存储器空间的分配和回收代码(C++)
#include"pch.h"
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<iomanip>
using namespace std;

#pragma warning(disable:4996)//避免strcpy错误,严重性代码说明项目文件行	禁止显示状态错误C4996	'strcpy': This function or variable may be unsafe.Consider using strcpy_s instead.To disable deprecation, use _CRT_SECURE_NO_WARNINGS.See online help for details.

const int MAXJOB = 100;  //定义表最大记录数
int F = 0;
typedef struct node {
	int start;     //空闲分区的起始地址
	int length;    //空闲分区的长度
	char tag[20];  //分区信息是否已分配
}job;

job frees[MAXJOB]; //定义空闲区表
int free_quantity; //空闲区的个数

job occupys[MAXJOB];//定义已分配区表
int occupy_quantity; //已分配区的个数

//初始化函数
void initial() {
	int i;



	for (i = 0;i < MAXJOB;i++) {

		frees[i].start = -1;
		frees[i].length = 0;
		strcpy(frees[i].tag, "free");

		occupys[i].start = -1;
		occupys[i].length = 0;
		strcpy(occupys[i].tag, "");
	}
	free_quantity = 0;
	occupy_quantity = 0;
	cout << "请输入要空闲区块的数量" << endl;
	int n;
	cin >> n;
	while (n--)
	{
		cout << "请输入空闲块的起始地址" << endl;
		cin >> frees[free_quantity].start;
		cout << "请输入空闲块的大小" << endl;
		cin >> frees[free_quantity].length;
		free_quantity++;
	}
}

//sort选择——排序
void sort() {
	int i, j, p;
	for (i = 0;i < free_quantity - 1;i++) {
		p = i;
		for (j = i + 1;j < free_quantity;j++)//空闲分区按地址递增的顺序排列
		{
			if (frees[j].start < frees[p].start)
			{
				p = j;
			}
		}
		if (p != i) {
			frees[free_quantity] = frees[i];
			frees[i] = frees[p];
			frees[p] = frees[free_quantity];
		}
	}
}

//显示函数
void view() {
	int i;
	cout << endl << "-------------------------------------------" << endl;
	cout << "当前空闲表:" << endl;
	cout << "起始地址 长度 状态" << endl;
	for (i = 0;i < free_quantity;i++) {
		cout.setf(2);
		cout.width(12);
		cout << frees[i].start;
		cout.width(10);
		cout << frees[i].length;
		cout.width(8);
		cout << frees[i].tag << endl;
	}
	cout << endl << "------------------------------------------" << endl;
	cout << "当前已分配表:" << endl;
	cout << "起始地址 长度 占用作业名" << endl;
	for (i = 0;i < occupy_quantity;i++) {
		cout.setf(2);
		cout.width(12);
		cout << occupys[i].start;
		cout.width(10);
		cout << occupys[i].length;
		cout.width(8);
		cout << occupys[i].tag << endl;
	}
}
int getF(int F, int job_length)
{
	for (int i = F; i < free_quantity; i++)
	{
		if (frees[i].length >= job_length)
		{
			return 1;
			break;
		}
	}
	return 0;
}
//循环首次适应分配算法
void cirearliest()
{
	char job_name[20];
	int job_length;
	int i, j, flag, t;
	cout << "请输入新申请内存空间的作业名和空间大小:";
	cin >> job_name;    //输入作业的名称
	cin >> job_length;  //输入作业的长度

	flag = 0;      //分配成功与否信号
	for (i = 0;i < free_quantity;i++)
	{
		if (frees[i].length >= job_length)
		{
			flag = 1; //可以分配
		}
	}
	if (flag == 0)
	{
		cout << endl << "Sorry,当前没有能满足你申请长度的空闲内存,请稍候再试" << endl;
	}
	else
	{
		t = 0;
		if (getF(F, job_length))
			//从空闲分区表顺序查找,直到找到第一能满足其大小要求的空闲分区为止
		{
			i = F;
			while (t == 0)
			{
				if (frees[i].length >= job_length)
				{
					t = 1;
				}
				i++;
			}
		}
		else
		{
			i = 0;
			while (t == 0)
			{
				if (frees[i].length >= job_length)
				{
					t = 1;
				}
				i++;
			}
		}
		i--;
		occupys[occupy_quantity].start = frees[i].start; //修改已分区的相关信息
		strcpy(occupys[occupy_quantity].tag, job_name);
		occupys[occupy_quantity].length = job_length;
		occupy_quantity++;
		F = i;
		if (frees[i].length > job_length)
		{
			frees[i].start += job_length;
			frees[i].length -= job_length;
		}
		else  //刚好分配则空闲分区数减一
		{
			for (j = i;j < free_quantity - 1;j++)
			{
				frees[j] = frees[j + 1];
			}
			free_quantity--;
			cout << "内存空间成功" << endl;
		}
	}

}
//最先适应分配算法
void earliest()
{
	//空闲分区按地址递增的顺序排列
	char job_name[20];
	int job_length;
	int i, j, flag, t;
	cout << "请输入新申请内存空间的作业名和空间大小:";
	cin >> job_name;    //输入作业的名称
	cin >> job_length;  //输入作业的长度

	flag = 0;      //分配成功与否信号
	for (i = 0;i < free_quantity;i++) {
		if (frees[i].length >= job_length) {
			flag = 1; //可以分配
		}
	}
	if (flag == 0) {
		cout << endl << "Sorry,当前没有能满足你申请长度的空闲内存,请稍候再试" << endl;
	}
	else {
		t = 0;
		i = 0;
		while (t == 0) {
			if (frees[i].length >= job_length)
				//从空闲分区表顺序查找,直到找到第一能满足其大小要求的空闲分区为止
			{
				t = 1;
			}
			i++;
		}
		i--;
		occupys[occupy_quantity].start = frees[i].start; //修改已分区的相关信息
		strcpy(occupys[occupy_quantity].tag, job_name);
		occupys[occupy_quantity].length = job_length;
		occupy_quantity++;
		F = i;
		if (frees[i].length > job_length)
		{
			frees[i].start += job_length;
			frees[i].length -= job_length;
		}
		else  //刚好分配则空闲分区数减一
		{
			for (j = i;j < free_quantity - 1;j++)
			{
				frees[j] = frees[j + 1];
			}
			free_quantity--;
			cout << "内存空间成功" << endl;
		}
	}
}
//最优适应分配算法
void excellent() {
	//空闲分区按大小递增的顺序排列
	char job_name[20];
	int job_length;
	int i, j, flag, t;

	cout << "请输入新申请内存空间的作业名和空间大小:";
	cin >> job_name;
	cin >> job_length;

	flag = 0;
	for (i = 0;i < free_quantity;i++)
	{
		if (frees[i].length >= job_length)
		{
			flag = 1;
		}
	}
	if (flag == 0)
	{
		cout << endl << "Sorry,当前没有能满足你申请长度的空闲内存,请稍候再试" << endl;
	}
	else
	{
		t = 0;
		i = 0;
		while (t == 0)
		{
			if (frees[i].length >= job_length) {
				t = 1;
			}
			i++;
		}
		i--;
		for (j = 0;j < free_quantity;j++)
		{
			if ((frees[j].length >= job_length) && (frees[j].length < frees[i].length))
			{
				i = j;
			}
		}

		occupys[occupy_quantity].start = frees[i].start;
		strcpy(occupys[occupy_quantity].tag, job_name);
		occupys[occupy_quantity].length = job_length;
		occupy_quantity++;
		F = i;
		if (frees[i].length > job_length)
		{
			frees[i].start += job_length;
			frees[i].length -= job_length;
		}
		else
		{
			for (j = i;j < free_quantity - 1;j++)
			{
				frees[j] = frees[j + 1];
			}
			free_quantity--;
			cout << "内存空间成功" << endl;
		}
	}
}

//最坏适应算法
void worst() {
	//空闲分区按大小递减的顺序排列
	char job_name[20];
	int job_length;
	int i, j, flag, t;

	cout << "请输入新申请内存空间的作业名和空间大小:";
	cin >> job_name;
	cin >> job_length;

	flag = 0;
	for (i = 0;i < free_quantity;i++) {
		if (frees[i].length >= job_length)
			flag = 1;
	}
	if (flag == 0)
		cout << endl << "Sorry,当前没有能满足你申请长度的空闲内存,请稍候再试" << endl;

	else {
		t = 0;
		i = 0;
		while (t == 0) {
			if (frees[i].length >= job_length)
				t = 1;
			i++;
		}
		i--;
		for (j = 0;j < free_quantity;j++) {
			if ((frees[j].length >= job_length) && (frees[j].length > frees[i].length))
				i = j;
		}

		occupys[occupy_quantity].start = frees[i].start;
		strcpy(occupys[occupy_quantity].tag, job_name);
		occupys[occupy_quantity].length = job_length;
		occupy_quantity++;
		F = i;
		if (frees[i].length > job_length)
		{
			frees[i].start += job_length;
			frees[i].length -= job_length;
		}
		else
		{
			for (j = i;j < free_quantity - 1;j++)
			{
				frees[j] = frees[j + 1];
			}
			free_quantity--;
			cout << "内存空间成功" << endl;
		}
	}
}

//撤消作业
void finished() {
	char job_name[20];
	int i, j, flag, p = 0;
	int start;
	int length;

	cout << "请输入要撤消的作业名:";
	cin >> job_name;

	flag = -1;
	for (i = 0;i < occupy_quantity;i++) {
		if (!strcmp(occupys[i].tag, job_name)) {
			flag = i;
			start = occupys[i].start;
			length = occupys[i].length;
		}
	}
	if (flag == -1) {
		cout << "没有这个作业名" << endl;
	}
	else
	{
		//加入空闲表
		for (i = 0;i < free_quantity;i++) {
			if ((frees[i].start + frees[i].length) == start)//上空
			{
				if (((i + 1) < free_quantity) && (frees[i + 1].start == start + length))
				{ //上空且下空,不为最后一个
					frees[i].length = frees[i].length + frees[i + 1].length + length;
					for (j = i + 1;j < free_quantity;j++)
						frees[j] = frees[j + 1];
					free_quantity--;
					p = 1;
				}
				else {
					frees[i].length += length; //上空且下不空
					p = 1;
				}
			}
			if (frees[i].start == (start + length)) { //下空
				frees[i].start = start;
				frees[i].length += length;
				p = 1;
			}
		}
		//空闲中没有
		if (p == 0) {
			frees[free_quantity].start = start;
			frees[free_quantity].length = length;
			free_quantity++;
		}
		//删除分配表中的该作业
		for (i = flag;i < occupy_quantity;i++)
			occupys[i] = occupys[i + 1];
		occupy_quantity--;
	}
}

void main()
{
	int t = 1;
	int chioce = 0;
	initial();
	while (1) {

		sort();
		cout << endl << endl << "=================================" << endl;
		cout << " 主存储器空间的分配与回收模拟" << endl;
		cout << "=============================================" << endl;
		cout << "1.首次适应算法申请空间 " << endl << "2.最佳适应算法申请空间"
			<< endl << "3.最坏适应算法申请空间" << endl << "4.循环首次适应算法申请空间" << endl << "5.撤消作业" << endl
			<< "6.显示空闲表和分配表 " << endl << "0.退出" << endl;
		cout << "请选择:";
		cin >> chioce;

		switch (chioce) {

		case 1:  earliest(); break;
		case 2:  excellent();break;
		case 3:  worst();break;
		case 5:  finished(); break;
		case 6:  view();  break;
		case 0:  exit(0); break;
		case 4:  cirearliest();break;
		default: cout << "选择错误!" << endl;
		}
	}
}

四、实验总结
(1)本次实验是有关内存空间分配的算法的实现,实验内容相对之前的进程调度稍微简洁些,但是基本实现的数据结构的线性表算法是一样的,还是需要通过申请空间,定义分区大小,然后通过线性表对各空闲分区进行相应的内存分配。
(2)虽然对实验步骤比较清晰,对最佳适应算法、最坏适应算法、首次适应算法和循环首次适应算法的知识理解得比较好,但是在对如何通过这些算法去实现这个内存分配的实验,还是遇到很多困难,比如visual studio2017不支持使用strcpy函数,通过查找资料也解决了这些问题。

标签:03,06,frees,job,free,start,length,2021,quantity
来源: https://blog.csdn.net/Vivian_0621/article/details/117520666