实验四主存空间的分配和回收
1. 目的和要求
1.1. 实验目的
用高级语言完成一个主存空间的分配和回收程序,以加深对动态分区分配方式及其算法的理解。
1.2. 实验要求
采用连续分配方式之动态分区分配存储管理,使用首次适应算法、循环首次适应算法、最佳适应算法和最坏适应算法4种算法完成设计。
(1)**设计一个作业申请队列以及作业完成后的释放顺序,实现主存的分配和回收。采用分区说明表进行。
(2)或在程序运行过程,由用户指定申请与释放。
(3)设计一个空闲区说明表,以保存某时刻主存空间占用情况。
把空闲区说明表的变化情况以及各作业的申请、释放情况显示。
2. 实验内容
根据指定的实验课题,完成设计、编码和调试工作,完成实验报告。
3. 实验环境
可以选用Visual C++作为开发环境。也可以选用Windows下的VB,CB或其他可视化环境,利用各种控件较为方便。自主选择实验环境。
4. 参考数据结构:
#include<stdio.h>
#include<conio.h>
#include<string.h>
#define MAX 24
struct partition{
char pn[10];
int begin;
int size;
int end; ////////
char status; //////////
};
typedef struct partition PART;
第一步:(第13周完成)
完成程序数据结构的创建,初始化内存分配情况,创建空闲分区表和已分配分区表。
第二步:(第14周完成)
完成为某作业分配内存空间。
- 用户输入作业名称;
- 判断作业名称是否已经存在,如果存在则要求用户重新输入;
- 用户输入作业所占空间大小;
- 判断是否能够在剩余的空闲区域中找到一块放置该作业,如果不行则要求用户重新输入;
- 显示菜单,由用户选择使用哪一种分配算法:
1) 首次适应算法
2) 循环首次适应算法
3) 最佳适应算法
4) 最坏适应算法
- 为该作业分配内存空间,分配处理流程图如下(size的值设定为1K):
- 屏幕显示分配后的内存分区情况。
第三步:(第15周完成)
完成内存空间回收;
- 由用户输入作业的ID,决定所要终止的作业;
- 判断是否存在用户所输入的ID,如果存在则进行终止,否则提示作业不存在;
- 判断即将终止的作业前后是否有空闲区域,如果没有则作业所占的空间独立成为一个空闲块,在未分配区表中增加一项;
(思考:如何判断前后是否有空闲块?)
- 即将终止作业所占空间前后有空闲块的情况:(X代表即将被终止的作业,黑色代表内存中的空闲块)
程序中表示内存区块的结构体如下:
struct partition {
char pn[10];
int begin;
int size;
int end;
char status;
};
所以,判断某个即将被终止的作业所占空间前面是否有空闲块的方法是:作业空间的起始地址A.begin是否等于某个空闲块的结束地址B.end,若相等,则前面有空闲块,则需要合并;若不相等则再判断后面是否有空闲块。
回答:如何判断?
- 进行四种情况的判断,然后分别做出相应的区块回收操作。
回答:如何处理回收?
- 显示回收后的内存使用情况。
源代码:
#include "stdio.h" 
#define N 5  
int start;//存放首址  
/*定义一个空闲区说明表结构,并初始化变量*/ 
struct freearea     
{   
	int startaddress;/*空闲区始址*/   
	int size;/*空闲区大小*/   
	int state;/*空闲区状态:0为空表目,1为可用空闲块*/  
}freeblock[N]={{20,20,1},{80,50,1},{150,30,1},{300,30,0},{600,10,1}}; /*定义为作业分配主存空间的函数alloc(),给首次适应算法调用*/ 
int alloc(int applyarea)  /*applyarea为作业申请量*/  
{   
	int i,tag=0;   /*tag为检查是否有满足作业需要的空闲区的标志*/   
	for(i=0;i<N;i++)  /*检查空闲区说明表是否有满足作业要求的空闲区*/   
		if(freeblock[i].state==1&&freeblock[i].size>applyarea)    
		{     
			freeblock[i].startaddress=freeblock[i].startaddress+applyarea;     
			freeblock[i].size=freeblock[i].size-applyarea;     
			tag=1;  /*有满足条件的空闲区时,tag置1*/     
			return freeblock[i].startaddress-applyarea;     
		}   
		else   if(freeblock[i].state==1&&freeblock[i].size==applyarea)    
		{     
			freeblock[i].state=0;     
			tag=1;  /*有满足条件的空闲区时,tag置1*/     
			return freeblock[i].startaddress; /*返回为作业分配的主存地址*/    
		}   
		if(tag==0)    
			return -1;  /*没有满足条件的空闲区,分配不成功,返回-1*/  
}    
/*定义为作业分配主存空间的函数alloc2(),给循环首次适应算法调用*/
int alloc2(int applyarea,int s)  /*applyarea为作业申请量*/ 
{   
	int i,tag=0;   /*tag为检查是否有满足作业需要的空闲区的标志*/   
	for(i=s;i<N;i++)/*检查空闲区说明表是否有满足作业要求的空闲区,从上次找到的空闲去的下一个空闲分区开始找*/   
		if(freeblock[i].state==1&&freeblock[i].size>applyarea)    
		{     
			freeblock[i].startaddress=freeblock[i].startaddress+applyarea;     
			freeblock[i].size=freeblock[i].size-applyarea;     
			tag=1;  /*有满足条件的空闲区时,tag置1*/              
			start=freeblock[i].startaddress-applyarea;              
			return i;     
		}   
		else if(freeblock[i].state==1&&freeblock[i].size==applyarea)    
		{     
			freeblock[i].state=0;     
			tag=1;  /*有满足条件的空闲区时,tag置1*/     
			start=freeblock[i].startaddress; /*返回为作业分配的主存地址*/     
			return i;    
		}       
		if(tag==0)    
			return -1;  /*没有满足条件的空闲区,分配不成功,返回-1*/ 
}  
/*定义为作业分配主存空间的函数alloc3(),给最佳适应算法调用*/
int alloc3(int applyarea)  /*applyarea为作业申请量*/ 
{   
	int i,k,h,tag=0,j=0;   /*tag为检查是否有满足作业需要的空闲区的标志*/   
	int a[N];   
	struct freearea min;   
	struct freearea mid;   
	for(i=0;i<N;i++)  /*检查空闲区说明表是否有满足作业要求的空闲区*/   
	{     
		if(freeblock[i].state==1&&freeblock[i].size==applyarea)//大小刚好相等    
		{     
			freeblock[i].state=0;     
			tag=1;  /*有满足条件的空闲区时,tag置1*/     
			return freeblock[i].startaddress; /*返回为作业分配的主存地址*/    
		}       
	}        
	for(i=0;i<N;i++)//把所有大于所要求的空闲区放入数组,挑出最小的那个       
	{           
		if(freeblock[i].state==1&&freeblock[i].size>applyarea)a[j++]=i;
	}          
	if(j>1)         
	{              
		h=a[0];             
		min=freeblock[h];       
		//min.startaddress=freeblock[h].startaddress;       
		//min.size=freeblock[h].size;       
		//min.state=freeblock[h].state;       
		for(k=1;k<j;k++)         
		{                
			h=a[k];                
			if(freeblock[h].size<min.size)               
			{         
				mid.size=freeblock[h].size;      
				mid.state=freeblock[h].state;      
				mid.startaddress=freeblock[h].startaddress;      
				freeblock[h].size=min.size;      
				freeblock[h].state=min.state;      
				freeblock[h].startaddress=min.startaddress;      
				min.size=mid.size;      
				min.state=mid.state;      
				min.startaddress=mid.startaddress;                
			}              
		}               
		min.startaddress=min.startaddress+applyarea;              
		min.size=min.size-applyarea;               
		tag=1; /*有满足条件的空闲区时,tag置1*/           
		return min.startaddress-applyarea;          
	}             
	else if(j==1)            
	{                
		h=a[0];                
		min=freeblock[h];                
		min.startaddress=min.startaddress+applyarea;               
		min.size=min.size-applyarea;         
		tag=1; /*有满足条件的空闲区时,tag置1*/            
		return min.startaddress-applyarea;            
	}           
	if(tag==0)    
		return -1;  /*没有满足条件的空闲区,分配不成功,返回-1*/  
}  
/*定义主存回收函数:setfree()  tag1代表释放区的高地址是否邻接一个空闲区,
tag2代表释放区的高低地址是否都邻接一个空闲区, 
tag3代表释放区的低地址是否邻接一个空闲区*/ 
void setfree()  
{   
	int s,l,tag1=0,tag2=0,tag3=0,i,j;   
	printf("input free area startaddress:\n");   
	scanf("%d",&s);  /*输入释放区的开始地址*/   
	printf("input free area size:\n");   
	scanf("%d",&l);  /*输入释放区的大小*/     
	for(i=0;i<N;i++)   
	{    
		if(freeblock[i].startaddress==s+l&&freeblock[i].state==1)    
		{     
			l=l+freeblock[i].size;     
			tag1=1;  /*有与释放区高地址邻接的空闲区,tag1置1*/     
			for(j=0;j<N;j++)      
				if(freeblock[j].startaddress+freeblock[j].size==s&&freeblock[j].state==1)      
				{       
					freeblock[i].state=0;       
					freeblock[j].size=freeblock[j].size+l;       
					tag2=1;/*有与释放区上下都邻接的空闲区,tag2置1*/       
					break;      
				}    
				if(tag2==0) /*无与释放区高低地址邻接的空闲区*/    
				{     
					freeblock[i].startaddress=s;     
					freeblock[i].size=l;     
					break;    
				}    
		}   
	}    
	if(tag1==0) /*无与释放区高地址邻接的空闲区,并检查是否低地址有邻接空闲区*/   
	{    
		for(i=0;i<N;i++)    
			if(freeblock[i].startaddress+freeblock[i].size==s&&freeblock[i].state==1)     
			{     
				freeblock[i].size=freeblock[i].size+l;     
				tag3=1; /*有与释放区低地址邻接的空闲区*/     
				break;     
			}    
			if(tag3==0)  /*无与释放区低地址邻接的空闲区*/     
				for(j=0;j<N;j++)
					 if(freeblock[j].state==0)/*找一个空表目,将释放区放入表中*/      
					 {       
						 freeblock[j].startaddress=s;       
						 freeblock[j].size=l;       
						 freeblock[j].state=1;       
						 break;      
					 }   
	}  
}  
/*定义对空闲区表中的空闲区调整的函数adjust(),  
使空闲区按始地址从小到大排列,
空表目放在最后面*/ 
void adjust()  
{   
	int i,j;   
	struct freearea middata;   
	for(i=0;i<N;i++)  /*将空闲区按始地址顺序在表中排列*/    
		for(j=0;j<N;j++)     
			if(freeblock[j].startaddress>freeblock[j+1].startaddress)     
			{      
				middata.startaddress=freeblock[j].startaddress;      
				middata.size=freeblock[j].size;      
				middata.state=freeblock[j].state;      
				freeblock[j].startaddress=freeblock[j+1].startaddress;      
				freeblock[j].size=freeblock[j+1].size;      
				freeblock[j].state=freeblock[j+1].state;      
				freeblock[j+1].startaddress=middata.startaddress;      
				freeblock[j+1].size=middata.size;      
				freeblock[j+1].state=middata.state;     
			}   
			for(i=0;i<N;i++) /*将空表目放在表后面*/    
				for(j=0;j<N;j++)     
					if(freeblock[j].state==0&&freeblock[j+1].state==1)      
					{       
						middata.startaddress=freeblock[j].startaddress;       
						middata.size=freeblock[j].size;       
						middata.state=freeblock[j].state;       
						freeblock[j].startaddress=freeblock[j+1].startaddress;       
						freeblock[j].size=freeblock[j+1].size;       
						freeblock[j].state=freeblock[j+1].state;       
						freeblock[j+1].startaddress=middata.startaddress;       
						freeblock[j+1].size=middata.size;       
						freeblock[j+1].state=middata.state;      
					} 
}
/*定义打印空闲区说明表函数:print()*/ 
void print()  
{   
	int i;      
	printf("  |        start        size        state        |\n");      
	for(i=0;i<N;i++)   
	{   
		printf("  |         %3d         %3d         %3d          |\n",     freeblock[i].startaddress,freeblock[i].size,freeblock[i].state);  
	}  
}    
//首次  
void firstFit() 
{        
	int applyarea,start,j;       
	char end;       
	getchar();    
	printf("\n 是否有作业等待? y or n:");    
	while((end=getchar())=='y')      
	{    
		printf("at first the free memory is this:\n");    
		adjust();   /*对空闲区表中的空闲区调整的函数*/    
		print();   /*打印空闲区表的初始状态*/    
		printf("input request memory size:");    
		scanf("%d",&applyarea);/*输入作业的申请量*/    
		start=alloc(applyarea);/*调用alloc()函数为作业分配空间,start为返回的始地址*/    
		if(start==-1)  /*alloc()分配不成功时,返回-1*/     
			printf("there is no fit memory,please wait\n");    
		else    
		{        
			adjust();        
			printf("after allocation,the free memory is this:\n");        
			print();   /*打印空闲区表*/     
			printf("job's memory start address is:%d\n",start);     
			printf("job size is:%d\n",applyarea);     
			printf("job is running.\n");     
			printf("job is terminated.\n");           
		}    
		for(j=1;j<100000;j++);/*延迟时间*/     
		setfree(); /*主存回收函数*/
		adjust();  /*调整空闲区说明表*/     
		print();  /*打印空闲区表函数*/     
		printf("是否有作业等待? y/n:");     
		end=getchar();/*是否有作业等待?有(Y)无(N)*/     
	} 
}   
//循环首次 
void nextFit() 
{        
	int applyarea,i=0,j;       
	char end;       
	getchar();    
	printf("\n 是否有作业等待? y or n:");    
	while((end=getchar())=='y')      
	{    
		printf("at first the free memory is this:\n");    
		adjust();   /*对空闲区表中的空闲区调整的函数*/    
		print();   /*打印空闲区表的初始状态*/    
		printf("input request memory size:");    
		scanf("%d",&applyarea);/*输入作业的申请量*/    
		if(i==N-1)    
		{             
			i=alloc2(applyarea,i);            
			if(i==-1)i=0;          
		}           
		else if(i<N-1)                    
			i=alloc2(applyarea,i);    //start=alloc2(applyarea,start);/*调用alloc2()函数为作业分配空间,start为返回的始地址*/    
		if(i==-1)  /*alloc2()分配不成功时,返回-1*/     
			printf("there is no fit memory,please wait\n");    
		else    
		{               
			adjust();        
			printf("after allocation,the free memory is this:\n");           
			print();   /*打印空闲区表*/     
			printf("job's memory start address is:%d\n",start);     
			printf("job size is:%d\n",applyarea);     
			printf("job is running.\n");     
			printf("job is terminated.\n");           
		}     
		for(j=1;j<100000;j++);/*延迟时间*/     
		setfree(); /*主存回收函数*/
		adjust();  /*调整空闲区说明表*/     
		print();  /*打印空闲区表函数*/     
		printf("是否有作业等待? y/n:");     
		end=getchar();/*是否有作业等待?有(Y)无(N)*/    
	} 
}   
//最佳适应算法 
void bestFit() 
{        
	int applyarea,start,j;       
	char end;       
	getchar();    
	printf("\n 是否有作业等待? y or n:");    
	while((end=getchar())=='y')      
	{    
		printf("at first the free memory is this:\n");    
		adjust();   /*对空闲区表中的空闲区调整的函数*/    
		print();   /*打印空闲区表的初始状态*/    
		printf("input request memory size:");    
		scanf("%d",&applyarea);/*输入作业的申请量*/    
		start=alloc3(applyarea);/*调用alloc()函数为作业分配空间,start为返回的始地址*/    
		if(start==-1)  /*alloc()分配不成功时,返回-1*/     
			printf("there is no fit memory,please wait\n");    
		else    
		{               
			adjust();        
			printf("after allocation,the free memory is this:\n");        
			print();   /*打印空闲区表*/     
			printf("job's memory start address is:%d\n",start);     
			printf("job size is:%d\n",applyarea);     
			printf("job is running.\n");     
			printf("job is terminated.\n");           
		}     
		for(j=1;j<100000;j++);/*延迟时间*/     
		setfree(); /*主存回收函数*/     
		adjust();  /*调整空闲区说明表*/     
		print();  /*打印空闲区表函数*/    
		printf("是否有作业等待? y/n:");     
		end=getchar();/*是否有作业等待?有(Y)无(N)*/    
	} 
}     
void FirstChoose()
{        
	printf("\t\t            请选择:                               \n");  
	printf("\t\t                a:首次适应                        \n");  
	printf("\t\t                b:循环首次                        \n"); 
	printf("\t\t                c:最佳适应                        \n");  
	printf("\t\t                d:退出                             \n");   
	printf("\n\t\t请选择操作方式: "); 
}   
/*主函数*/ 
main()  
{       
	char s;       
	FirstChoose();   
	s=getchar();   
	while(s!='d')
	{     
		switch(s)   
		{          
			case'a': 
				firstFit();    
				break;          
			case'b': 
				nextFit();    
				break;         
			case'c': 
				bestFit();    
				break;   
			case'd':    
				break;
			default:
				printf("error\n");    
				break;       
		}     
		FirstChoose();     
		s=getchar();   
	}     
	return 0; 
}
 
                    
                     
                    
                 
                    
                 
         
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号