计算机操作系统 实验五:动态分区分配方式的模拟

1 .实验目的

了解动态分区分配方式中使用的数据结构和分配算法,并进一步加深对动态分区存储管理方式及其实现过程的理解。

2 .实验内容

(1)用C 语言分别实现采用首次适应算法(地址从小到大)和最佳适应算法(空闲块大小从小到大)的动态分区分配过程myalloc() 和回收过程myfree()(即自己编写一个分区分配和释放的函数) 。其中,空闲分区通过空闲分区链来管理;在进行内存分配时,系统优先使用空闲区低端的空间。

(2)假设初始状态下,可用的内存空间为640 KB(即程序开始运行时,用malloc()函数一次申请640KB的内存空间,程序结束时用free()函数释放空间。然后自己编写程序在这640KB的空间上模拟首次适应算法和最佳适应算法的分配过程。自己编写的分配过程不是真正去向操作系统申请空间,而是在这640KB空间上标记那块占用了;释放过程也不是真正释放空间,只是标记哪块分区空闲),作业请求序列如下:

  1. 作业l 申请130 KB 。
  2. 作业2 申请60 KB 。
  3. 作业3 申请100 KB 。
  4. 作业2 释放60 KB 。
  5. 作业4 申请200 KB 。
  6. 作业3 释放100 KB 。
  7. 作业l 释放130 KB 。
  8. 作业5 申请140 KB 。
  9. 作业6 申请60 KB 。
  10. 作业7 申请50 KB 。
  11. 作业6 释放60 KB 。

请分别采用首次适应算法和最佳适应算法进行内存块的分配和回收,要求每次分配和回收后显示出空闲内存分区链的情况。

3 .实验步骤

不想看示例的话,可以直接向下滑到最后一步看代码

1.首次适应算法

模拟作业请求序列分配:

 

自由分配:

1.分配空间足够的情况

2.分配空间不足的情况

3.普通回收

首先分配一些内存准备回收,此时内存初始情况如下

4.连续回收

继上次内存情况回收任务2,此时应连续回收地址1-250的内存

当三个内存块需要连续回收时,回收任务4,此时所有内存块都空闲,需要连续回收

 

2.最佳适应算法

模拟作业请求序列分配:

 

自由分配:

1.体现出最佳适应的普通分配

分配任务6,大小为50kb。如果按照首次适应算法则会从地址101-300的内存块分配给任务,而最佳适应算法会寻找大小最小且满足条件的内存块,即从地址为551-640的内存块分配给任务6.

2.回收:

连续回收两个内存块

连续回收三个内存块

全部回收

 

4 .完整代码(C语言实现)

#include<stdio.h>
#include<stdlib.h>
struct nodespace{
	int teskid;   // 任务号 
	int begin;    // 开始地址 
	int size;     // 大小 
	int status;   // 状态 0代表占用,1代表空闲 
	struct nodespace *next;  // 后指针 
};

void initNode(struct nodespace *p){
	if(p == NULL){	//如果为空则新创建一个 
		p = (struct nodespace*)malloc(sizeof(struct nodespace));
	}
	p->teskid = -1;
	p->begin = 0;
	p->size = 640;
	p->status = 1;
	p->next =NULL; 
}

/*
*  首次适应算法 
*/ 
void myMalloc1(int teskid,int size,struct nodespace *node){
	while(node != NULL){
		if(node->status == 1){  //空闲的空间 
			if(node->size > size){  //当需求小于剩余空间充足的情况 
				//分配后剩余的空间 
				struct nodespace *p = (struct nodespace*)malloc(sizeof(struct nodespace));
				p->begin = node->begin + size;
				p->size = node->size - size;
				p->status = 1;
				p->teskid = -1;
				//分配的空间 
				node->teskid = teskid; 
				node->size = size;
				node->status = 0;
				//改变节点的连接 
				p->next = node->next; 
				node->next = p;
				break; 
			}else if(node->size == size){ //需求空间和空闲空间大小相等时 
				node->teskid = teskid; 
				node->size = size;
				node->status = 0;
				break;
			}	
		}
		if(node->next == NULL){
			printf("分配失败,没有足够的空间!\n");
			break;
		}
		node = node->next;
	}
} 

/*
* 最佳适应算法 
*/
void myMalloc2(int teskid,int size,struct nodespace *node){
	//最佳块指针 
	struct nodespace *q = NULL;
	//首先找到第一个满足条件的空闲块 
	while(node != NULL){
		if(node->status == 1 && node->size >= size){
			q = node;
			break;
		}
		//如果下一个为空则说明没有空闲区可以分配 
		if(node->next == NULL){
			printf("分配失败,没有足够的空间!\n");
			break;
		} else{
			node = node->next;	
		}
		
	} 
	//遍历寻找最佳的空闲块 
	while(node != NULL){
		if(node->status == 1 && node->size >= size && node->size < q->size){  //空闲的空间 
			q = node;
		}
		node = node->next;
	}
	if(q->size > size){  			//最佳空闲块的大小大于需求大小 
		//分配后剩余的空间 
		struct nodespace *p = (struct nodespace*)malloc(sizeof(struct nodespace));
		p->begin = q->begin + size;
		p->size = q->size - size;
		p->status = 1;
		p->teskid = -1;
		//分配的空间 
		q->teskid = teskid; 
		q->size = size;
		q->status = 0;
		//改变节点的连接 
		p->next = q->next; 
		q->next = p;
	}else if(q->size == size){  	//最佳空闲块空间大小和需求相等
		q->teskid = teskid; 
		q->size = size;
		q->status = 0;
	}		
}

void myFree(int teskid,struct nodespace *node){
	if(node->next == NULL && node->teskid == -1){
		printf("还没有分配任何任务!\n");
	}
	
	while(node != NULL){
		if(node->status == 1 && node->next->status ==0 && node->next->teskid == teskid){  //释放空间的上一块空间空闲时 
			node->size = node->size + node->next->size;
			struct nodespace *q = node->next;
			node->next = node->next->next;
			free(q);
			if(node->next->status == 1){ //下一个空间是空闲空间时 
				node->size = node->size + node->next->size;
				struct nodespace *q = node->next;
				node->next = node->next->next;
				free(q);
			}
			break;
		}else if(node->status == 0 && node->teskid == teskid){  //释放空间和空闲空间不连续时 
			node->status = 1;
			node->teskid = -1;
			if(node->next != NULL && node->next->status == 1){ //下一个空间是空闲空间时 
				node->size = node->size + node->next->size;
				struct nodespace *q = node->next;
				node->next = node->next->next;
				free(q);
			}
			break;
		}else if(node->next == NULL){  //任务id不匹配时 
			printf("没有此任务!\n");
			break;
		}
		node = node->next;
	}
	
	 
}

void printNode(struct nodespace *node){
	printf("                        内存情况                        \n"); 
	printf(" -------------------------------------------------------\n");
	printf("| 起始地址\t结束地址\t大小\t状态\t任务id\t|\n");
	while(node != NULL){
		if(node->status==1){
			printf("| %d\t\t%d\t\t%dKB\tfree\t 无\t|\n", node->begin + 1, node->begin+node->size, node->size);
		}else{
			printf("| %d\t\t%d\t\t%dKB\tbusy\t %d\t|\n", node->begin + 1, node->begin+node->size, node->size, node->teskid);
		}
		node = node->next;
	}
	printf(" -------------------------------------------------------\n");
}

void destory(struct nodespace *node){
	struct nodespace *q = node;
	while(node != NULL){
		node = node->next;
		free(q);
		q = node;
	}
}

void menu(){
	printf("1.分配内存\n");
	printf("2.回收内存\n");
	printf("3.查看内存情况\n");
	printf("4.退出\n");
	printf("请输入选项:");
}

int main(){
	// node为整个空间 
	struct nodespace *init = (struct nodespace*)malloc(sizeof(struct nodespace));
	struct nodespace *node = NULL;
	initNode(init);			//初始化主链 
	node = init; 			//指向链表头 
	int option; 
	int teskid;
	int size;
	while(1){
		printf("请选择模式:\n 1.演示模式\n 2.自由模式\n 3.退出\n");
		scanf("%d",&option);
		if(option == 1){	//演示模式 
			while(1){		//循环选择实现的算法 
				printf("请选择算法:\n 1.首次适应算法\n 2.最佳适应算法\n 3.退出\n");
				scanf("%d",&option);
				if(option == 1){			//首次适应算法 
					printf("作业1 申请130 KB\n");
					myMalloc1(1,130,node);		//作业1 申请130 KB
					printNode(node);
					printf("作业2 申请60 KB\n");
					myMalloc1(2,60,node);		//作业2 申请60 KB
					printNode(node);
					printf("作业3 申请100 KB\n");
					myMalloc1(3,100,node);		//作业3 申请100 KB
					printNode(node);
					printf("作业2 释放60 KB\n");
					myFree(2,node);			//作业2 释放60 KB
					printNode(node);
					printf("作业4 申请200 KB\n");
					myMalloc1(4,200,node);		//作业4 申请200 KB
					printNode(node);
					printf("作业3 释放100 KB\n");
					myFree(3,node);			//作业3 释放100 KB
					printNode(node);
					printf("作业1 释放130 KB\n");
					myFree(1,node);			//作业1 释放130 KB
					printNode(node);
					printf("作业5 申请140 KB\n");
					myMalloc1(5,140,node);		//作业5 申请140 KB
					printNode(node);
					printf("作业6 申请60 KB\n");
					myMalloc1(6,60,node);		//作业6 申请60 KB
					printNode(node);
					printf("作业7 申请50 KB\n");
					myMalloc1(7,50,node);		//作业7 申请50 KB
					printNode(node);
					printf("作业6 释放60 KB\n");
					myFree(6,node);			//作业6 释放60 KB
					printNode(node);
					destory(node);	//销毁链表
					initNode(init);	//重新初始化 
					node = init;	//重新指向开头 
				}else if(option == 2){		//最佳适应算法 
					printf("作业1 申请130 KB\n");
					myMalloc2(1,130,node);		//作业1 申请130 KB
					printNode(node);
					printf("作业2 申请60 KB\n");
					myMalloc2(2,60,node);		//作业2 申请60 KB
					printNode(node);
					printf("作业3 申请100 KB\n");
					myMalloc2(3,100,node);		//作业3 申请100 KB
					printNode(node);
					printf("作业2 释放60 KB\n");
					myFree(2,node);			//作业2 释放60 KB
					printNode(node);
					printf("作业4 申请200 KB\n");
					myMalloc2(4,200,node);		//作业4 申请200 KB
					printNode(node);
					printf("作业3 释放100 KB\n");
					myFree(3,node);			//作业3 释放100 KB
					printNode(node);
					printf("作业1 释放130 KB\n");
					myFree(1,node);			//作业1 释放130 KB
					printNode(node);
					printf("作业5 申请140 KB\n");
					myMalloc2(5,140,node);		//作业5 申请140 KB
					printNode(node);
					printf("作业6 申请60 KB\n");
					myMalloc2(6,60,node);		//作业6 申请60 KB
					printNode(node);
					printf("作业7 申请50 KB\n");
					myMalloc2(7,50,node);		//作业7 申请50 KB
					printNode(node);
					printf("作业6 释放60 KB\n");
					myFree(6,node);			//作业6 释放60 KB
					printNode(node);
					destory(node);	//销毁链表
					initNode(init);	//重新初始化 
					node = init;	//重新指向开头 
				}else if(option == 3){		//退出
					break;
				}else{
					printf("您的输入有误,请重新输入!\n"); 
				}
			} 	
		}else if(option == 2){	//自由模式 
			while(1){		//循环选择使用的算法 
				printf("请选择算法:\n 1.首次适应算法\n 2.最佳适应算法\n 3.退出\n");
				scanf("%d",&option);
				int n = option;		//标记选择的算法,n == 1 表示首次适应算法, n == 2表示最佳适应算法 
				if(option != 3){
					while(1){
						menu();		//打印想要进行的操作 
						scanf("%d",&option);
						if(option == 1 && n == 1){			//首次适应 
							printf("请输入任务id以及申请的空间大小:\n");
							scanf("%d%d",&teskid,&size);
							myMalloc1(teskid,size,node);
							printNode(node);
						}else if(option == 1 && n == 2){	//最佳适应 
							printf("请输入任务id以及申请的空间大小:\n");
							scanf("%d%d",&teskid,&size);
							myMalloc2(teskid,size,node);
							printNode(node);
						}else if(option == 2){
							printf("请输入任务id:\n");
							scanf("%d",&teskid);
							myFree(teskid,node);
							printNode(node);
						}else if(option == 3){
							printNode(node);
						}else if(option == 4){
							destory(node);	//销毁链表
							initNode(init);	//重新初始化 
							node = init;	//重新指向开头 
							break;
						}else{
							printf("您的输入有误,请重新输入!\n");
							continue;
						}
					}
				}else if(option == 3){
					destory(node);	//销毁链表
					initNode(init);	//重新初始化 
					node = init;	//重新指向开头 
					break;
				}
				else{
					printf("您的输入有误,请重新输入!\n");
				}
			} 
				
		}else if(option == 3){	//退出  
			destory(node);
			return 0;
		}else {
			printf("您的输入有误,请重新输入!\n");
			continue;
		}
	}
	return 0;
}

 

如果文章对你有帮助的话点个赞鼓励一下吧!

  • 107
    点赞
  • 405
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值