1. 程式人生 > >記憶體管理模擬實驗之實現一個簡單的固定(可變)分割槽儲存管理系統

記憶體管理模擬實驗之實現一個簡單的固定(可變)分割槽儲存管理系統

#include<stdlib.h>
#include<stdio.h>
#include<iostream.h>
#include<string.h>
#include<iomanip.h>

const int MAXJOB=5;//定義表最大記錄數
typedef struct node
{
	int front;
	int length;
	char data[20];
}job;//定義job型別的資料型別

job frees[MAXJOB];//定義空閒區表
int free_quantity;

job occupys[MAXJOB];//定義已分配區表
int occupy_quantity;

//初始化並建立空閒分割槽表函式
int initial()
{
	int i;
	frees[0].front=0;
	frees[0].length=30;
	occupys[0].front=0;
	occupys[0].length=0;
	strcpy(frees[0].data,"free");
	for(i=1;i<MAXJOB;i++)
		{
			frees[i].front=frees[i-1].front+frees[i-1].length;
			frees[i].length=frees[i-1].length+20;
			strcpy(frees[i].data,"free");
			occupys[i].front=0;
			occupys[i].length=0;
			strcpy(occupys[i].data," ");
		}
	free_quantity=MAXJOB;
	occupy_quantity=0;
	return 1;
}


//顯示函式
void show()
{
	int i;
	printf("----------------------------------------------------------\n");
	printf("當前空閒分割槽表如下:\n");
	printf("起始地址     長度      狀態\n");
	for(i=0;i<free_quantity;i++)
	{
		printf("%5d   %8d       %s\n",frees[i].front,frees[i].length,frees[i].data);
	}
	printf("----------------------------------------------------------\n");
	printf("當前已分配表如下:\n");
	printf("起始地址    長度    佔用作業名\n");
	for(i=0;i<occupy_quantity;i++)
	{
		printf("%5d     %6d       %s\n",occupys[i].front,occupys[i].length,occupys[i].data);
	}
	printf("----------------------------------------------------------\n");
}


//首次適應分配演算法
void assign()
{
	char job_name[20];
	int job_length;
	int i,j,flag,t;
	printf("請輸入新申請記憶體空間的作業名和空間大小:");
	scanf("%s",job_name);
	scanf("%d",&job_length);
	flag=0;
	for(i=0;i<free_quantity;i++)
	{
		if(frees[i].length>=job_length) //如果空閒空間I的長度>=作業長度
		{
		   flag=1;   //空閒標誌位就置1
		}
	}
	if(flag==0)
	{
		printf("對不起,當前沒有能滿足你申請長度的空閒記憶體,請稍候再試!\n");
	}
	else
	{
		t=0;
		i=0;
		while(t==0)   //為空閒區間的時候
		{
		   if(frees[i].length>=job_length)
		   {
				t=1;
		   }
		   i++;//如果空閒空間I的長度不大於作業長度,I加1,判斷下一個空間
		}
		i--;
		occupys[occupy_quantity].front=frees[i].front;//把未用的空閒空間的首地址付給已用空間的首地址
		strcpy(occupys[occupy_quantity].data,job_name);//已用空間的內容為作業名
		occupys[occupy_quantity].length=job_length;//已用空間的長度為作業的長度
		occupy_quantity++;      //已用空間數量加1
		if(frees[i].length>job_length) //如果空間的長度大於作業的長度,
		{
		   frees[i].front+=job_length; //空閒空間的起始首地址=原空閒區間的起始長度加作業長度
		   frees[i].length-=job_length;//空閒區間的長度=原空閒區間的長度-作業的長度
		}
		else                         //如果空間的長度=作業的長度
		{//相等的話,往前移一位,採用list好一點
		   for(j=i;j<free_quantity-1;j++)
		   {
				frees[j]=frees[j+1];//空閒區間前移一位
		   }
		   free_quantity--;//空閒區間的數量減一
		}
		printf("記憶體空間分配成功!\n");
	}
}


//撤消作業   
void cancel()
{
	char job_name[20];
	int i,j,flag,p=0;
	int start;
	int len;
	printf("請輸入要撤消的作業名:");
	scanf("%s",job_name);
	flag=0;
	for(i=0;i<occupy_quantity;i++)
	{
	if(!strcmp(occupys[i].data,job_name))//當輸入作業名匹配時
	{
	   flag=i;//把i的值賦給flag;
	   start=occupys[i].front;//把已用空間的首地址賦給start
	   len=occupys[i].length;//把已用空間的長度賦給len
	}
	}
	if(flag==0)
	{
	printf("沒有這個作業名,請重新輸入作業名!\n");
	}
	else
	{                 //加入空閒表
	for(i=0;i<free_quantity;i++)
	{
	   if((frees[i].front+frees[i].length)==start)//上空
	   {
		   if(((i+1)<free_quantity)&&(frees[i+1].front==start+len))//下空
		{
	   //第i個空閒區間的長度=第i個空閒區間的長度+第i+1個空閒區間的長度(下空閒區)+length
			 frees[i].length=frees[i].length+frees[i+1].length+len;
			 for(j=i+1;j<free_quantity;j++)
	   {
			   frees[j]=frees[j+1];//空閒區間前移一位
	   }
			  free_quantity--;//空閒區的數量漸少了一個
			p=1;
		}
		   else 
		{
		   frees[i].length+=len;//(上空下不空)第i個空閒區間的長度=第i個空閒區間的長度+length,空閒區個數不變
		   p=1;
		}
	   }
	   if(frees[i].front==(start+len))//下空上不空
	   {
		frees[i].front=start;//起始地址等於待回收地址
		frees[i].length+=len;//第i個空閒區間的長度=第i個空閒區間的長度+length
		p=1;
	   }
	}
	if(p==0) //上下空閒區都不空(直接在空閒區表中找一個空表目,將其內容插入)
	{
	   frees[free_quantity].front=start;
	   frees[free_quantity].length=len;
	   free_quantity++;   //空閒區的數量加1
	}
	   //刪除分配表中的該作業
	for(i=flag;i<occupy_quantity;i++)
	{
	   occupys[i]=occupys[i+1];
	}
	occupy_quantity--;//已用的區的數量
	printf("記憶體空間回收完畢!\n");
	}
}

//主函式
void main()
{
	int flag=0;
	int t=1;
	int chioce=0;
	printf(" |--------------------------------------------------|\n");
	printf(" |     可變分割槽儲存管理模擬系統            |\n");
	printf(" |--------------------------------------------------|\n");
	printf(" |選單: (0)退出                               |\n");
	printf(" |                                          |\n");
	printf(" |    (1)申請空間     (2)撤消作業              |\n");
	printf(" |                                          |\n");
	printf(" |    (3)顯示空閒表和分配表                     |\n");                                          
	printf(" |--------------------------------------------------|\n");
	initial();
	flag=initial(); 
	while(flag==1)
	{
		printf("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n");
		printf("請選擇:");
		scanf("%d",&chioce);
		switch(chioce)
		{
		case 1:
			assign(); break;
		case 2:
			cancel(); break;
		case 3: 
			show();    break;
		case 0: 
			flag=0; break;
		default:
			printf("選擇錯誤!");
		}
	}
}