【操作系统】可变分区存储管理,模拟实现

1.目的和要求

通过这次实验,加深对内存管理的认识,进一步掌握内存的分配、回收算法的思想。

2.实验内容

阅读教材《计算机操作系统》第四章,掌握存储器管理相关概念和原理。

编写程序模拟实现内存的动态分区法存储管理。内存空闲区使用自由链管理,采用最坏适应算法从自由链中寻找空闲区进行分配,内存回收时假定不做与相邻空闲区的合并

假定系统的内存共640K,初始状态为操作系统本身占用64K。在t1时间之后,有作业A、B、C、D分别请求8K、16K、64K、124K的内存空间;在t2时间之后,作业C完成;在t3时间之后,作业E请求50K的内存空间;在t4时间之后,作业D完成。要求编程序分别输出t1、t2、t3、t4时刻内存的空闲区的状态。

3.实验环境

Windows操作系统、VC++6.0

C语言


好的,废话完毕,当然!!你要知道我想干嘛上面的还是看一看比较好大笑

废话不多上代码

/*
 * 功能:假定系统的内存共640K,初始状态为操作系统本身占用64K。在t1时间之后,
		有作业A、B、C、D分别请求8K、16K、64K、124K的内存空间;在t2时间之后,
		作业C完成;在t3时间之后,作业E请求50K的内存空间;在t4时间之后,作业D完成。
		要求编程序分别输出t1、t2、t3、t4时刻内存的空闲区的状态。
 * 时间:2014年5月10日14:06:55
 * 作者:cutter_point
*/

#include <iostream>
#include <stdio.h>

using namespace std;


/************************************************************************************/
//首先定下自由链表数据结构,存放空的空间
typedef struct FreeStack
{
	int len,address;		//len是分区的长度,address是分区的起始地址
	struct FreeStack *next;	//指向下一个分区
}*FreeLink;

//然后是已经占用的空间链表
typedef struct BusyStack
{
	char name;		//占用当前分区的作业名字
	int len,address;		//占用的长度和起始地址
	struct BusyStack *next;		//指向下一个分区
}*BusyLink;

/************************************************************************************/
//设置全程变量
FreeLink free_head=NULL;		//自由链表的头指针
BusyLink busy_head=NULL,		//占用区的头指针
		 busy_tail=NULL;		//占用区的尾指针
/************************************************************************************/
//各级子函数
//1.初始化函数
void start()
{
	FreeLink p;
	BusyLink q;
	
	//初始化头指针
	free_head=(FreeLink)malloc(sizeof(FreeStack));
	free_head->next=NULL;
	busy_head=busy_tail=(BusyLink)malloc(sizeof(BusyStack));
	busy_head->next=NULL;

	//初始化时候OS占用的空间为64k,自由链
	p=(FreeLink)malloc(sizeof(FreeStack));
	p->address=64; p->len=640-64; p->next=NULL;
	free_head->next=p;

	//初始化占用链,S是系统占用的
	q=(BusyLink)malloc(sizeof(BusyStack));
	q->address=0;	q->len=64;	q->name='S';	q->next=NULL;
	busy_head->next=q;	busy_tail=q;

}

//2.模拟内存分配函数
void requireMemo(char name , int require)
{
	//需要用到的几个指针
	FreeLink w,u,v;
	BusyLink p;

//首先判断空余空间是否可以被满足!
	if(free_head->next->len >= require)
	{
		//首先吧要求的信息存放到一个节点上
		p=(BusyLink)malloc(sizeof(BusyStack));
		p->name=name;
		p->address=free_head->next->address;
		p->len=require;
		p->next=NULL;

		//吧这个节点接到占用队列上!
		busy_tail->next=p;
		busy_tail=p;
		cout<<p->name<<":得到分配,起始分配地址为:"<<p->address<<endl;

		//吧空闲分区链的第一个节点取出来
		w=free_head->next;
		free_head->next=w->next;
		w->next=NULL;

		//判断空间是否恰好适合
		if(w->len != require)
		{
			//超过了的话,那么就要吧占用的减掉
			w->address += require;
			w->len -= require;
			
			//处理完成后接回到原来的链表上
			u=free_head;	v=free_head->next;
			//执行插入链表操作,如果没有到最后一个元素,并且v的长度比当前的要插入的w大的话
			//由于最坏适应算法,所以要把小的放后面,即w还要往后找
			while(v != NULL && v->len > w->len)
			{
				u=v;
				v=v->next;
			}

			//吧w插入到v的前面u的后面
			u->next=w;
			w->next=v;
		//	cout<<"空闲分区减少,起始地址变为:"<<free_head->next->address<<endl;


		}
		else
			free(w);
	}
	else
	{
		cout<<"********************************"<<endl;
		cout<<"***完了!你得要求太高无法满足!***"<<endl;
		cout<<"********************************"<<endl;
		return;
	}
}

//3.模拟内存回收
void freeMemo(char name)
{
	FreeLink w,u,v;
	BusyLink q,p;
	int address,len;

	//首先找到要回收的块在那
	q=busy_head;
	p=busy_head->next;
	while (p != NULL && p->name != name)
	{//如果不是当前的,那么就进入下一个
		q=p;
		p=p->next;
	}

	//找到了码?还是到了链表尾
	if(p == NULL)
	{
		cout<<name<<"is not find!"<<endl;
		return;
	}

	//由于尾指针是单个的指针,要特殊考虑
	//吧这个节点取出来,回收
	if(p == busy_tail)
		busy_tail=q;
	//吧p取出来
	q->next=p->next;
	p->next=NULL;

	//吧p的信息记录下来
	address=p->address;
	len=p->len;
	cout<<p->name<<"的空间被回收!"<<endl;
	free(p);

	//吧回收的空间放入空闲链表
	//准备一个节点插入空闲链表
	w=(FreeLink)malloc(sizeof(FreeStack));
	w->address=address;
	w->len=len;
	w->next=NULL;
	//找到要插入的位置
	u=free_head;
	v=u->next;
	while (v != NULL && v->len > w->len)
	{
		//如果不是到了表尾,或者是当前的要插入的节点不是比v大的话那么就向后找
		u=v;
		v=v->next;
	}

	//不论是到了表尾还是没到直接插入都是这样,而且空闲链表没有表尾指针
	//差到v前面,u后面
	u->next=w;
	w->next=v;


}

//4.模拟内存进过的时间
void past(char time)
{
	cout<<"***********************************"<<endl;
	cout<<"*我们经过漫长的等待过了 "<<time<<" 年。。。*"<<endl;
	cout<<"***********************************"<<endl;
}

//5.输出内存空闲情况
void printlink()
{
	//通过循环来输出链表,自由链表
	FreeLink u,v;
	u=free_head;
	v=free_head->next;
	int i=1;
	while(v != NULL)
	{
		cout<<"第 "<<i<<" 块空闲块起始地址是:"<<v->address<<"大小是:"<<v->len<<endl;
		u=v;
		v=v->next;
		i++;
	}
}

/************************************************************************************/
//主函数搞起
int main()
{
	char t1,t2,t3,t4;
	start();

	cout<<"-------------------------------------------------------------------"<<endl;
	cout<<"已经过了多少时间?"<<endl;
	cin>>t1;

	past(t1);
	requireMemo('A',8);  requireMemo('B',16); 
	requireMemo('C',64); requireMemo('D',124);
	printlink();

	cout<<"-------------------------------------------------------------------"<<endl;
	cout<<"已经过了多少时间?"<<endl;
	cin>>t2;

	past(t2);
	freeMemo('C');
	printlink();

	cout<<"-------------------------------------------------------------------"<<endl;
	cout<<"已经过了多少时间?"<<endl;
	cin>>t3;

	past(t3);
	requireMemo('E',50);
	printlink();
	freeMemo('D' );
	printlink();

	return 0;
}

完成了,这个玩意花了一下午,真是蛋疼,主要花时间的是想算法,编程其实有思路了后写出来是很快的!!!

总结一下:

写程序很总要的一点就死算法,有了算法上面都不怕,分分钟程序就可以上来,

所以以后学习的时候重点是思路,多想,思考,光无脑堆代码感觉是没有用的!!生气大笑

模拟实现动态可变分区存储管理系统,内存资源的分配情况用一个单链表来表示,每一个节点表示一个可变分区,记录有内存首地址、大小、使用情况等,模拟内存分配动态输入构造空闲区表,键盘接收内存申请尺寸大小,根据申请,实施内存分配,并返回分配所得内存首址。分配完后,调整空闲区表,并显示调整后的空闲区表和已占用的区表。如果分配失败,返回分配失败信息。模拟内存回收。根据空闲区表,从键盘接收回收区域的内存作业代号。回收区域,调整空闲区表,并显示调整后的空闲区表。对于内存区间的分配,移出,合并就是相应的对链表节点信息进行修改,删除和创建相应的节点。 在模拟实现动态可变分区存储管理系统中用到的是“最佳适应算法”与“最坏适应算法”。所谓“最佳”是指每次为作业分配内存时,总是把满足要求、又是最小的空闲分区分配给作业,避免“大材小用”。因此保证每次找到的总是空闲分区中最小适应的,但这样会在储存器中留下许多难以利用的小的空闲区。最坏适应分配算法是要扫描整个空闲分区表或链表,总是挑选最大的一个空闲分区割给作业使用。进入系统时我们需要内存首地址和大小这些初始化数据。成功后我们可以自由的使用首次适应算法与最佳适应算法对内存进行分配。内存经过一系列分配与回收后,系统的内存分配情况不再连续。首次适应算法与最佳适应算法的差异也就很容易的体现在分配时。动态可变分区存储管理模拟系统采用最佳适应算法、最坏适应算法内存调度策略,对于采用不同调度算法,作业被分配到不同的内存区间。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值