操作系统-内存管理、分配和回收模拟实验

思路:采用链表管理,利用伙伴关系,即控制empty表和work表的内存总和刚好等于此片内存区域大小
对每一种添加程序的算法,在执行前,先对empty表按照相应要求进行重排序,即:
1.最佳适应:empty表按照内存区域大小从小到大排序
2.首次适应:empty表按照内存首地址大小从小到大排序
3.最坏适应:empty表按照内存区域大小从大到小排序

对于回收内存时的上下连接检查:在checkAdress函数中进行,若存在连接区域,则对empty链表节点进行删除和修改

算法本身不难,主要是搞清楚三种算法的要求,笔者对于数组的使用很不习惯, 所以使用的是链表,大家也可以用数组活着别的数据结构形式改写,另外笔者排版上有点儿丑,很难受,代码量不大,仔细思考构思框架以后对于初学者基本半天以内解决。

尊重原创,转载注明出处:https://blog.csdn.net/kr2563

// Exercise3.cpp: 定义控制台应用程序的入口点。
//

/*
思路:采用链表管理,利用伙伴关系,即控制empty表和work表的内存总和刚好等于此片内存区域大小
对每一种添加程序的算法,在执行前,先对empty表按照相应要求进行重排序,即:
1.最佳适应:empty表按照内存区域大小从小到大排序
2.首次适应:empty表按照内存首地址大小从小到大排序
3.最坏适应:empty表按照内存区域大小从大到小排序

对于回收内存时的上下连接检查:在checkAdress函数中进行,若存在连接区域,则对empty链表节点进行删除和修改
*/

#include "stdafx.h"
#include 
#include 
#define yz 2    //定义阈值为2
using namespace std;

int sum = 0;   //记录内存区域的整个大小
int alreadyUse = 0;  //记录已经使用的内存区域大小


/*定义内存结构体*/
struct space {
	int begin;  //起始地址
	int length;  //长度
	string name;  //程序的名字
	space *next;
};
typedef space *Space;

/*初始化, 此时empty起始地址为内存首地址,长度为整个内存区间,work表为空*/
void Init( Space empty, Space work, int length) {
	empty->next = NULL;
	work->next = NULL;
	empty->begin = 0;
	empty->length = length;
}


/*首次适应*/
void firstSuit(Space empty) {
	space* temp1 = empty;
	space* temp2 = empty;
	if (empty == NULL)
		return;
	for (;temp1->next != NULL;temp1 = temp1->next)
	{
		for (temp2 = empty;temp2->next != NULL;temp2 = temp2->next)
		{
			if (temp2->begin > temp2->next->begin)
			{
				int temp = temp2->length;
				int begin = temp2->begin;
				temp2->length = temp2->next->length;
				temp2->begin = temp2->next->begin;
				temp2->next->length = temp;
				temp2->next->begin = begin;
			}
		}
	}
}

/*最坏适应*/
void worsestSuit(Space empty) {
	space* temp1 = empty;
	space* temp2 = empty;
	if (empty == NULL)
		return;
	for (;temp1->next != NULL;temp1 = temp1->next)
	{
		for (temp2 = empty;temp2->next != NULL;temp2 = temp2->next)
		{
			if (temp2->length > temp2->next->length)
			{
				int temp = temp2->length;
				int begin = temp2->begin;
				temp2->length = temp2->next->length;
				temp2->begin = temp2->next->begin;
				temp2->next->length = temp;
				temp2->next->begin = begin;
			}
		}
	}
}

/*最好适应*/
void bestSuit(Space empty) {
	space* temp1 = empty;
	space* temp2 = empty;
	if (empty == NULL)
		return;
	for (;temp1->next != NULL;temp1 = temp1->next)
	{
		for (temp2 = empty;temp2->next != NULL;temp2 = temp2->next)
		{
			if (temp2->length < temp2->next->length)
			{
				int temp = temp2->length;
				int begin = temp2->begin;
				temp2->length = temp2->next->length;
				temp2->begin = temp2->next->begin;
				temp2->next->length = temp;
				temp2->next->begin = begin;
			}
		}
	}
}



/*根据程序添加的方式对empty链表进行排序*/
void sortBychoice(Space empty, int choice) {
	switch (choice)
	{
	case 1:
		firstSuit(empty);
		break;
	case 2:
		worsestSuit(empty);
		break;
	case 3:
		bestSuit(empty);
		break;
	default:
		cout << "*        未知的选择,默认当前选择!        *" << endl;
		break;
	}
}


/*遍历打印empty表*/
void displayEmpty(Space empty) {
	cout << endl << endl << "*        empty        *" << endl << endl;
	if (empty == NULL) {
		cout << "*        无可申请空间!        *" << endl;
		return;
	}
	space *temp = new space;
	temp = empty;
	cout << "begin" << "\t" << "length" << "\t" << "状态" << endl;
	while (temp) {
		cout << temp->begin << "\t" << temp->length << "\t" << "未分配" << endl;
		temp = temp->next;
	}
	cout << endl;
}


/*遍历打印work表*/
void displayWork(Space work) {
	cout << endl << endl << "*        work        *" << endl << endl;
	if (work == NULL) {
		cout << "*        无可回收内存!        *" << endl;
		return;
	}
	space *temp = new space;
	temp = work->next;
	cout << "begin" << "\t" << "length" << "\t" << "程序名" << endl;
	while (temp) {
		cout << temp->begin << "\t" << temp->length <<"\t" << temp->name.c_str() << endl;
		temp = temp->next;
	}
}

/*添加新的程序*/
void Create(Space empty, Space work) {
	int choice;
	int length;
	int m = 0;
	char name[10];
	cout << "*        请选择添加算法 :        *" << endl;
	cout << "*        1:  首次适应算法        *" << endl;
	cout << "*        2:  最佳适应算法        *" << endl;
	cout << "*        3:  最坏适应算法        *" << endl;
	cin >> choice;
	sortBychoice(empty, choice);
	displayEmpty(empty);
	cout << "*        输入程序需要的长度: ";
	cin >> length;
	if (length > sum - alreadyUse) {
		cout << "*        当前剩余存储区域不足以满足需求,拒绝继续添加程序" << endl;
		return;
	}
	cout << "*        输入申请内存的程序名: ";
	cin >> name;
	space *temp = new space;
	space *preTemp = new space;
	preTemp = empty;
	temp = empty;
	while (temp) {
		if (temp->length > length) {
			//若差值小于阈值
			if (temp->length - length <= yz) {
				//判断是否是第一个结点
				if (temp == empty) {
					space *prog = new space;
					prog->begin = temp->begin;
					prog->length = temp->length;
					prog->name = (string)name;
					space *workList = new space;
					workList = work;
					while (workList->next) {
						workList = workList->next;
					}
					prog->next = workList->next;
					workList->next = prog;
					empty = empty->next;
				}
				else {
					space *prog = new space;
					preTemp->next = temp->next;
					prog->begin = temp->begin;
					prog->length = temp->length;
					prog->name = (string)name;
					space *workList = new space;
					workList = work;
					while (workList->next) {
						workList = workList->next;
					}
					prog->next = workList->next;
					workList->next = prog;
				}
			}
			else {
				space *prog = new space;
				prog->begin = temp->begin;
				prog->length = length;
				temp->begin = temp->begin + length;
				temp->length = temp->length - length;
				prog->name = (string)name;
				space *workList = new space;
				workList = work;
				while (workList->next) {
					workList = workList->next;
				}
				prog->next = workList->next;
				workList->next = prog;
			}
			break;
		}
		temp = temp->next;
		if (m == 1)
			preTemp = preTemp->next;
		m = 1;
	}
	displayWork(work);
	cout << endl;
	displayEmpty(empty);
}

/*统计empty表长度*/
int getLength(Space empty) {
	int length = 0;
	space *temp = new space;
	temp = empty;
	while (temp)
	{
		length++;
		temp = temp->next;
	}
	return length;
}

/*检查地址*/
void checkAddress(Space empty) {
	space *temp = new space;
	space *preTemp = new space;
	temp = empty;
	while (temp) {
		if (temp->next) {
			if (temp->begin + temp->length == temp->next->begin) {
				temp->length = temp->length + temp->next->length;
				temp->next = temp->next->next;
			}
		}
		temp = temp->next;
	}
	preTemp = empty;
	temp = preTemp->next;
	//对末尾结点的检查
	while (temp) {
		if (temp->next == NULL) {
			if (temp->begin == preTemp->begin + preTemp->length) {
				preTemp->length = preTemp->length + temp->length;
				preTemp->next = NULL;
				break;
			}
		}
		temp = temp->next;
		preTemp = preTemp->next;
	}
}


/*回收已有的程序*/
void callBack(Space empty, Space work) {
	string name;
	int len;
	int begin;
	int length;
	int flag = 0;   //用于判断输入是否正确
	displayWork(work);
	cout << "*        输入将要回收的程序名: ";
	cin >> name;
	space *tempWork = new space;
	space *preTempwork = new space;
	space *tempEmpty = new space;
	tempWork = work->next;
	preTempwork = work;
	tempEmpty = empty;
	while (tempWork) {
		if (!tempWork->name.compare(name)){
			flag = 1; //寻找到目标程序
			begin = tempWork->begin;
			length = tempWork->length;
			len = getLength(empty);
			preTempwork->next = tempWork->next; //从work表中删除该节点
			while (tempEmpty){
				space *newEmpty = new space;
				newEmpty->begin = begin;
				newEmpty->length = length;
				newEmpty->name = "未分配";
				if (len >= 2) {
					if (tempEmpty->begin  > begin) {
						newEmpty->begin = tempEmpty->begin;
						newEmpty->length = tempEmpty->length;
						tempEmpty->begin = begin;
						tempEmpty->length = length;
						newEmpty->next = tempEmpty->next;
						tempEmpty->next = newEmpty;
						break;
					}
				}
				else {
					if (begin < tempEmpty->begin) {
						newEmpty->begin = tempEmpty->begin;
						newEmpty->length = tempEmpty->length;
						tempEmpty->begin = begin;
						tempEmpty->length = length;
						newEmpty->next = tempEmpty->next;
						tempEmpty->next = newEmpty;

					}
					else {
						newEmpty->next = tempEmpty->next;
						tempEmpty->next = newEmpty;
					}
					break;
				}
				tempEmpty = tempEmpty->next;    //这里不在第一次查询到就break是因为程序可能被分段存储的
			}
		}
		tempWork = tempWork->next;
		preTempwork = preTempwork->next;
	}
	if (flag == 0)
		cout << "未查询到将要回收的程序段,请重新选择!" << endl;
	else {
		//合并内存
		firstSuit(empty);
		checkAddress(empty);
	}
	displayWork(work);
	displayEmpty(empty);
}



int main()
{
	int choice, length;
	Space empty, work;
	empty = new space;
	work = new space;
	cout << "输入最大的内存容量: ";
	cin >> length;
	sum = length;   //将整体的长度赋值给全局变量
	Init(empty, work, length);   //	empty  ---> 空闲的区域  work --->  装入程序的区域
								
	while (1) {
		cout << "*************************" << endl;
		cout << "*        1:添加作业     *" << endl;
		cout << "*        2:回收内存     *" << endl;
		cout << "*        3:退出程序     *" << endl;
		cout << "*        请选择:        *" << endl;
		cin >> choice;
		switch (choice) {
		case 1:
			Create(empty, work);
			break;
		case 2:
			callBack(empty, work);
			break;
		case 3:
			cout << "*				   谢谢使用!				   *" << endl;
			exit(0);
		}
	}
    return 0;
}

 

你可能感兴趣的:(操作系统内存管理,分配与模拟实验)