⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 主存空间的分配与回收.cpp

📁 操作系统实验和实验报告
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "stdio.h"
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include "iostream.h"
#define getjcb(type)  (type*)malloc(sizeof(type))
#define getsub(type)  (type*)malloc(sizeof(type))
#define NULL 0

int num,num2;  //要调度的作业数和要回收的区域数
int m=0;     //已分配作业数
int flag;     //分配成功标志
int isup,isdown;   //回收区域存在上邻和下邻的标志
int is=0;

struct jcb
{
	char name[10];
	char state;
	int ntime; //所需时间
	int size;  //所需空间大小
    int addr;  //所分配分区的首地址
	struct jcb *link;
} *ready =NULL, *p,*q,*as=NULL;
//作业队列ready,已分配作业队列as
typedef struct jcb JCB;

struct subarea{         //分区块
	char name[10];
	int addr;    //分区首地址
	int size;    //分区大小
	char state;
	struct subarea *link;
} *sub=NULL,*r,*s,*cur;
//空闲分区队列sub,当前分区指针cur
typedef struct subarea SUB;

//--------------------------------------------------------------------------
void sort_sub()     /*对空闲分区按从小到大排序*/
{   
	SUB *first,*second;
    int insert=0;
    if((sub==NULL)||((s->size)<(sub->size)))   /*插在队列之首*/
	{
		s->link=sub;
		sub=s;
	}
    else
	{
		first=sub;        /*寻找适当的位置插入*/
	    second=first->link;
		while(second!=NULL)
		{
			if((s->size)<(second->size))
			{
			   s->link=second;
			   first->link=s;
			   second=NULL;
			   insert=1;
			}
			else
			{
                first=first->link;
			    second=second->link;
			}
		 }
		 if(insert==0)first->link=s;   /*插在队尾*/
	}
} 

//--------------------------------------------------------------------------
void firstsort() /* 建立对作业按到达时间进行排列的函数,直接插在队列之尾 sort*/
{
	JCB *first;
	if(ready==NULL)  ready=p;
	else
	{
		first=ready;
		while(first->link!=NULL)
			first=first->link;
		first->link=p;
		p->link=NULL;
	}
}

//--------------------------------------------------------------------------
void lastsort()      /*建立对已分配作业队列的排列函数,直接插在队列之尾sort3*/
{
	JCB *fir;
	if(as==NULL) as=q;
	else
	{
		fir=as;
		while(fir->link!=NULL)
			fir=fir->link;
		fir->link=q;
		q->link=NULL;
	}
	m++;
}


//--------------------------------------------------------------------------   
void input() /* 建立作业控制块函数*/
{
	int i;
	printf("\n请输入要调度的总作业数:");
	scanf("%d",&num);
	for(i=0;i<num;i++)
	{
	   printf("\n作业号No.%d:\n",i);
	   p=getjcb(JCB);
	   printf("\n输入作业名:");
	   scanf("%s",&p->name);
	   printf("\n输入作业的大小:");
	   scanf("%d",&p->size);
	   printf("\n输入作业所需运行时间:");
	   scanf("%d",&p->ntime);
	   p->state='w';
	   p->link=NULL;
	   firstsort(); /* 调用sort函数*/
	}
	printf("\n 按任一键继续......\n");
	getch();
}

//--------------------------------------------------------------------------
void input2()     /*建立要回收区域的函数*/
{
	 JCB *k;
	 int has;
	 q=getjcb(JCB);
	 printf("\n输入区域名(作业名):");
	 scanf("%s",&q->name);
	 p=as;
	 while(p!=NULL)
	 {
		 if(strcmp(p->name,q->name)==0)  /*在已分配作业队列中寻找*/
		 {
				q->addr=p->addr;
				q->size=p->size;
				has=1;    /*输入作业名存在标志位*/
				if(p==as)  as=p->link;    /*在已分配作业队列中删除该作业*/
				else
				{
					k=as;
					while(k->link!=p)  k=k->link;
					k->link=k->link->link;      /*删除*/
				}
				printf("输出该作业首地址:%d\n",q->addr);
				printf("输出该作业大小:%d\n\n",q->size);
				q->link=NULL;
				break;
		}
		else
		   {p=p->link; has=0;}   /*输入作业名不存在标志*/
	}
	if(has==0)
	{
		printf("\n输入作业名错误!请重新输入!\n");
		input2();
	}  
}

//--------------------------------------------------------------------------
void init_sub()       /*初始化空闲分区表*/
{
	 r=getsub(SUB);
	 strcpy(r->name,"one"); r->addr=5; r->size=10; r->state='n';
	 sub=r;
	 s=getsub(SUB);
	 strcpy(s->name,"two"); s->addr=20; s->size=120; s->state='n';
	 sub->link=s;r=s;
	 s=getsub(SUB);
	 strcpy(s->name,"three"); s->addr=160; s->size=40; s->state='n'; 
	 r->link=s;r=s;
	 s=getsub(SUB);
	 strcpy(s->name,"four"); s->addr=220; s->size=10; s->state='n'; 
	 r->link=s;r=s;
	 s=getsub(SUB);
	 strcpy(s->name,"five"); s->addr=250; s->size=20; s->state='n'; 
	 r->link=s;
	 s->link=NULL;
}


//--------------------------------------------------------------------------
void disp()    /*空闲分区表的显示函数*/
{
	 printf("\t\t 分区          首地址           长度          状态 \n");
	 r=sub;
	 while(r!=NULL)
	 {
		printf("\t\t %s\t\t%d\t\t%d\t\t%c\n",r->name,r->addr,r->size,r->state);
		r=r->link;
	 }
	 printf("\n");
}

//--------------------------------------------------------------------------
void disp2()   /*显示已分配内存的作业表函数*/
{
	 printf("\t\t 作业名         首地址          长度          状态 \n");
	 p=as;
	 while(p!=NULL)
	 {
		printf("\t\t %s\t\t%d\t\t%d\t\t%c\n",p->name,p->addr,p->size,p->state);
		p=p->link;
	 }
	 printf("\n\n");
}

//--------------------------------------------------------------------------
void perfit(JCB *pr) /*最佳适应作业分区assign*/
{
	 SUB *k;
	 r=sub;
	 while(r!=NULL)
	 {
		if(((r->size)>(pr->size))&&(r->state=='n'))   /*有空闲分区大于作业大小的情况*/
		{
			pr->addr=r->addr;
			r->size-=pr->size;
			r->addr+=pr->size;
			if(r==sub) sub=r->link;     /*删除空闲分区*/ 
			else 
			{
				s=sub;
				while(s->link!=r)  s=s->link;
				s->link=s->link->link;      /*删除空闲分区*/ 
			}
			flag=1;       /*分配成功标志位置1*/
			q=pr;
			lastsort();    /*插入已分配作业队列*/
			//重新插入剩余空闲分区,插在合适位置
			if(r->size<sub->size)   /*插入队首*/
			{
				r->link=sub;
				sub=r;
			}
			else   /*插在适当的位置*/
			{
				s=sub;
				while((s->size)<=(r->size))   s=s->link;
				k=sub;
				if(k==s)  {r->link=sub->link; sub=r;}   /*插在队首的后一个位置*/
				else   /*第二个以后的位置*/
				{
					while(k->link!=s)  k=k->link;
					 r->link=s;    
					k->link=r;
				}	
			 }
			 printf("作业%s的分区为[%s],首地址为%d.\n",p->name,r->name,pr->addr);  
			 break;   	   
		} 
		else if(((r->size)==(pr->size))&&(r->state=='n'))    /*有空闲分区等于作业大小的情况*/
		{
		   pr->addr=r->addr;
		   flag=1;    /*分配成功标志位置1*/
		   q=pr;
		   lastsort();	     /*插入已分配作业队列*/
		   s=sub;        /*空闲分区已完成分配,应删除*/
		   while(s->link!=r)  s=s->link;
		   s->link=s->link->link;	 /*删除空闲分区*/  
		   printf("作业%s的分区为[%s],首地址为%d.\n",p->name,r->name,pr->addr); 
		   break;
		}
		else 
		{r=r->link;  flag=0;}
	}
	if(flag==0)           /*作业过大的情况*/
	{
		printf("作业%s长度过大,内存不足,分区分配出错!\n",p->name);
		is=1;
	}
}

//--------------------------------------------------------------------------
void firstfit(JCB *pr) /*首次适应作业分区*/
{
	//SUB *k;
	r=sub;   /*从空闲表头开始寻找*/
	while(r!=NULL)
	{
		if(((r->size)>(pr->size))&&(r->state=='n'))   /*有空闲分区大于作业大小的情况*/
		{
			pr->addr=r->addr;
			r->size-=pr->size;
			r->addr+=pr->size;
		    flag=1;       /*分配成功标志位置1*/
		    q=pr;
		    q->state='r';
		    lastsort();     /*插入已分配作业队列*/
		    printf("作业%s的分区为[%s],首地址为%d.\n",p->name,r->name,pr->addr);
		    break;
		}
		else if(((r->size)==(pr->size))&&(r->state=='n'))    /*有空闲分区等于作业大小的情况*/
		{
		   pr->addr=r->addr;
		   flag=1;    /*分配成功标志位置1*/
		   q=pr;
		   lastsort();	    /*插入已分配作业队列*/
		   s=sub;       /*空闲分区已完成分配,应删除*/
		   while(s->link!=r)  s=s->link;
		   s->link=s->link->link;	 /*删除空闲分区*/
		   printf("作业%s的分区为[%s],首地址为%d.\n",p->name,r->name,pr->addr);
		   break;
		}
		else
        {r=r->link;  flag=0;}
	}
	if(flag==0)           /*作业过大的情况*/
	{
		printf("作业%s长度过大,内存不足,分区分配出错!\n",p->name);
		is=1;
	}
}

//--------------------------------------------------------------------------
void cyclefit(JCB *pr) /*循环首次适应作业分区*/
{
	SUB *k;
	r=cur;   /*从当前指针开始寻找*/
	while(r!=NULL)
	{
		if(((r->size)>(pr->size))&&(r->state=='n'))   /*有空闲分区大于作业大小的情况*/
		{
		   pr->addr=r->addr;
		   r->size-=pr->size;
		   r->addr+=pr->size;
		   flag=1;       /*分配成功标志位置1*/
		   cur=r;        /*更新当前指针*/
		   q=pr;
		   q->state='r';
		   lastsort();             /*插入已分配作业队列*/
		   printf("作业%s的分区为[%s],首地址为%d.\n",p->name,r->name,pr->addr);
		   break;
		}
		else if(((r->size)==(pr->size))&&(r->state=='n'))    /*有空闲分区等于作业大小的情况*/
		{
		   pr->addr=r->addr;
		   flag=1;    /*分配成功标志位置1*/
		   cur=r;
		   q=pr;
		   lastsort();	    /*插入已分配作业队列*/
		   s=sub;      /*空闲分区已完成分配,应删除*/
		   while(s->link!=r)  s=s->link;
		   s->link=s->link->link;	 /*删除空闲分区*/
		   printf("作业%s的分区为[%s],首地址为%d.\n",p->name,r->name,pr->addr);
		   break;
		}
		else
		{
			r=r->link;
			if(r==NULL)      /*当前指针为空时,重新由空闲区队列之首寻找*/
			{
			   k=cur;  /*作保存当前指针用*/
			   cur=sub;  
			   r=cur;
			}
			if(k==r)   /*又回到开始的指针时,确定为没有空间满足要求*/
			{
			   cur=k;  
			   break;
			}
			flag=0;  /*分配不成功标志*/
		}
	}
	if(flag==0)           /*作业过大的情况*/
	{
		printf("作业%s长度过大,内存不足,分区分配出错!\n",p->name);
		is=1;
	}
}


//--------------------------------------------------------------------------
void less_to_more()  /*把分区按大小从小到大排序*/
{
	r=sub;
	sub=NULL;
	while(r!=NULL)
	{
		s=r;
		r=s->link;
		s->link=NULL;
		sort_sub(); /*调用排序函数*/
	}
}

//--------------------------------------------------------------------------
void reclperfit(JCB *pr)       /*最佳适应回收区域,按分区大小排列*/
{ 
	SUB *k;
	r=sub;
	while(r!=NULL)
	{
		if(r->addr==((pr->addr)+(pr->size)))     /*回收区域有下邻*/
		{
			pr->size+=r->size;
			s=sub;
			isdown=1;     /*下邻标志位置1*/
			while(s!=NULL)
			{
				if(((s->addr)+(s->size))==(pr->addr))   /*有下邻又有上邻*/
				{
					s->size+=pr->size;
					k=sub;
					while(k->link!=r)  k=k->link;
					k->link=k->link->link;
					isup=1;      /*上邻标志位置1*/    
					break;
				}
				else 
				{s=s->link; isup=0;}    /*上邻标志位置0*/  
			}
 			if(isup==0)               /*有下邻无上邻*/
			{ 
				r->addr=pr->addr;
				r->size=pr->size;
			}
			break;	   
		}
		else 
		{r=r->link; isdown=0;}     /*下邻标志位置0*/  
	}  
	if(isdown==0)              /*区域无下邻*/
    { 
		s=sub; 
		while(s!=NULL) 
		{
			if(((s->addr)+(s->size))==(pr->addr))   /*无下邻但有上邻*/
			{ 
				s->size+=pr->size; 
				isup=1;        /*上邻标志位置1*/
				break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -