首次適應演算法
最佳適應演算法C++程序:
struct list // 初始化數據的結構體
{
int num;
int adr;
int end;
int size;
}s[]={{1,1000,2999,2000},{2,500,799,300},{3,3500,3699,200},{4,4000,4499,500}}; // 初始化空閑分區
/*void print(struct list *p,int n) // print函數作用輸出結果
{
int flag1=1;
int flag2=1;
int i,j=0;
cout<<"-------------------------------------\n";
for(i=0;i {
if(p->size==0) // 控制不輸出size=0的空閑塊
{
flag2=0;
j++;
continue;
}
else
flag2=1;
if(p->size!=0&&flag2!=0)
{
flag1=0;
cout<<"序號:"<num-j/*輸出的序號仍然是從1開始*//*<<" 起始位置:"<adr<<" 終止位置:"<end<<" 空閑塊大小:"<size< }
}
if(flag1==1) // 當所有的空閑塊正好被分配完時
cout<<"\n空閑內存已被分配完,請回收!\n";
cout<<"-------------------------------------\n";
}*/
void print(struct list a[],int n) // print函數作用輸出結果
{
int i;
cout<<"-------------------------------------\n";
if(a[0].size==0)
{
for(i=0;i {
a[i].adr=a[i+1].adr;
a[i].size=a[i+1].size;
a[i].end=a[i+1].end;
}
k=k-1;
}
if(k==0)
cout<<"\n空閑塊已經分配完畢,需要再分配,請回收!\n";
for(i=0;i cout<<"序號:"< cout<<"-------------------------------------\n";
}
未完。請自己從參考資料上復制。
② 首次適應演算法,最佳適應演算法和最壞適應演算法怎麼分配資源
首次適應演算法要求空閑分區鏈以空閑分區開始地址遞增的次序鏈接,從鏈首開始順序查找,直至找到一個能滿足程序大小要求的空閑分區為止
最佳適應演算法技能滿足要求,又是最小的空閑分區
最差適應演算法總是找到一個滿足程序長度要求的最大空閑分區
③ 採用首次適應演算法和最優置換演算法,對內存的分配和回收速度會造成什麼不同的影響
首次適應分配演算法(FF):
對空閑分區表記錄的要求是按地址遞增的順序排列的,每次分配時,總是從第1條記錄開始順序查找空閑分區表,找到第一個能滿足作業長度要求的空閑區,分割這個空閑區,一部分分配給作業,另一部分仍為空閑區。
最佳置換演算法(OPT):
選擇以後永不使用或在最長時間內不再被訪問的內存頁面予以淘汰。
④ 求操作系統首次適應演算法,要求內存分配大小自己定,分配後還有多大內存,總之就是建立二級菜單
問題一:⑴ 存儲管理的實質是什麼?(對內存的管理,主要對內存中用戶區進行管理)⑵ 多道程序中,為方便用戶和充分利用內存以提高內存利用率,內存管理的任務是什麼?(內存空間的分配和回收、內存空間的共享、存儲保護、地址映射、內存擴充)。⑶ 如何實現存儲保護? 答:在多道程序系統中,內存中既有操作系統,又有許多用戶程序。為使系統正常運行,避免內存中各程序相互干擾,必須對內存中的程序和數據進行保護。1、防止地址越界對進程所產生的地址必須加以檢查,發生越界時產生中斷,由操作系統進行相應處理。2、防止操作越權對屬於自己區域的信息,可讀可寫;對公共區域中允許共享的信息或獲得授權可使用的信息,可讀而不可修改;對未獲授權使用的信息,不可讀、不可寫。存儲保護一般以硬體保護機制為主,軟體為輔,因為完全用軟體實現系統開銷太大,速度成倍降低。當發生越界或非法操作時,硬體產生中斷,進入操作系統處理(4) 物理存儲器分幾類?(內存、外存、緩存)⑸ 虛存儲器的含義是什麼?(兩層含義)答:虛存儲器有兩層含義,一是指用戶程序的邏輯地址構成的地址空間;二是指當內存容量不滿足用戶要求時,採用一種將內存空間與外存空間有機地結合在一起,利用內外存自動調度的方法構成一個大的存儲器,從而給用戶程序提供更大的訪問空間。⑹ 什麼叫物理地址?什麼叫邏輯地址?什麼叫地址映射?地址映射分哪幾類?(靜態、動態)答:物理地址是內存中各存儲單元的編號,即存儲單元的真實地址,它是可識別、可定址並實際存在的。用戶程序經過編譯或匯編形成的目標代碼,通常採用相對地址形式,其首地址為零,其餘指令中的地址都是相對首地址而定。這個相對地址就稱為邏輯地址或虛擬地址。邏輯地址不是內存中的物理地址,不能根據邏輯地址到內存中存取信息。為了保證CPU執行程序指令時能正確訪問存儲單元,需要將用戶程序中的邏輯地址轉運行時可由機器直接定址的物理地址,這一過程稱為地址映射或地址重定位。地址映射可分為兩類:1、靜態地址映射2、動態地址映射問題二:⑴ 怎樣對內存進行分區?(靜態、動態;等長、不等長)答:對內存空間的劃分是可以靜態的,也可以動態的;可以是等長的,也可以不等長。靜態劃分是指系統運行之前就將內存空間劃分成若干區域,通常,分配給進程的內存可能比進程實際所需的區域長。動態劃分是在系統運行過程中才劃分內存空間。這樣,系統可按進程所需要的存儲空間大小為其分配恰好滿足要求的一個或多個區域。等長分區是將存儲空間劃分為若干個長度相同的區域。不等長分區則是將存儲空間劃分若干個長度不同的區域。⑵ 根據分區情況,從如何實現進程的內存分配?答:1、靜態等長分區的分配2、動態異長分區的分配⑶ 什麼叫碎片?(零散的小空閑區) 怎樣解決碎片問題?(緊湊技術)答:所謂碎片是指內存中出現的一些零散的小空閑區域。解決碎片的方法是移動所有佔用區域,使所有的空閑區合並成一片連續區域。這一過程稱為緊湊,這一技術就是緊湊技術。。問題三:⑴ 存儲管理方案有哪些?(分區管理、頁式管理、段式管理、段頁式管理、虛擬存儲管理)⑵ 分區管理的基本思想是什麼?主要缺點是什麼?基本思想:將內存劃分成若干連續的區域,稱為分區,每個分區裝入一個運行作業。主要缺點:不能充分利用內存,也不能實現對內存的擴充。⑶ 什麼是固定分區?什麼是可變分區?各有什麼優缺點?答:固定分區:系統將內存劃分為若干固定的分區,當作業申請內存時,系統為其選擇一個適當的分區,並裝入內存運行。由於分區大小是事先固定的,因而可容納作業的大小受到限制,而且當用戶作業的地址空間小於分區的存儲空間時,浪費了一些存儲空間。可變分區:是指在作業裝入內存時建立分區,使分區的大小正好與作業要求的存儲空間相等。引入可變分區方法,使內存分配有較大的靈活性,也提高了內存利用率。但是可變分區會引起碎片的產生。⑷ 分區管理可以採用的內存分配策略是什麼?首先適應演算法、最佳適應演算法、最壞適應演算法。⑸ 為實現地址映射和存儲保護,系統為用戶程序提供了哪些寄存器?基址寄存器、限長寄存器;上界寄存器、下界寄存器。問題四:⑴ 試述頁式存儲管理的基本原理① 內存劃分。② 邏輯地址空間劃分。③ 頁面大小。④ 內存分配。⑵ 試述頁式存儲管理的實現方法①
⑤ 首次適應演算法的介紹
首次適應演算法從空閑分區表的第一個表目起查找該表,把最先能夠滿足要求的空閑區分配給作業,這種方法目的在於減少查找時間。為適應這種演算法,空閑分區表(空閑區鏈)中的空閑分區要按地址由低到高進行排序。該演算法優先使用低址部分空閑區,在低址空間造成許多小的空閑區,在高地址空間保留大的空閑區。
⑥ 在採用首次適應演算法回收內存時,可能出現哪幾種情況應怎麼樣處理這些情況
a. 回收區與插入點的前一個分區相鄰接,此時可將回收區與插入點的前一分區合並,不再為回收分區分配新表項,而只修改前鄰接分區的大小;
b. 回收分區與插入點的後一分區相鄰接,此時合並兩區,然後用回收區的首址作為新空閑區的首址,大小為兩者之和;
c. 回收區同時與插入點的前後兩個分區鄰接,此時將三個分區合並,使用前鄰接分區的首址,大小為三區之和,取消後鄰接分區的表項;
d. 回收區沒有鄰接空閑分區,則應為回收區單獨建立一個新表項,填寫回收區的首址和大小,並根據其首址,插入到空閑鏈中的適當位置.
⑦ 求用C語言寫出首次適應分配演算法的分配過程~
/********************************
內存管理模擬程序
*******************************/
#include<iostream.h>
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include <time.h>
#include <windows.h>
/*定義宏*/
#define TotalMemSize 1024 /*劃分的物理塊的大小,地址范圍0~1023*/
#define MinSize 2 /*規定的不再分割的剩餘分區的大小*/
#define getpch(type) (type*)malloc(sizeof(type))
/*定義內存塊*/
typedef struct memBlock
{
struct memBlock *next;/*指向下一個塊*/
int stAddr; /*分區塊的初始地址*/
int memSize; /*分區塊的大小*/
int status; /*分區塊的狀態,0:空閑,1:以被分配*/
}MMB;
/*定義全局變數*/
MMB *idleHead=NULL; /*空閑分區鏈表的頭指針*/
MMB *usedHead=NULL; /*分配分區鏈表的頭指針*/
MMB *usedRear=NULL; /*分配分區鏈表的鏈尾指針*/
MMB *np; /*循環首次適應演算法中指向即將被查詢的空閑塊*/
int idleNum=1;/*當前空閑分區的數目*/
int usedNum=0;/*當前已分配分區的數目*/
MMB *memIdle=NULL; /*指向將要插入分配分區鏈表的空閑分區*/
MMB *memUsed=NULL; /*指向將要插入空閑分區鏈表的已分配分區*/
int flag=1;/*標志分配是否成功,1:成功*/
/*函數聲明*/
void textcolor (int color);/*輸出著色*/
void InitMem();/*初始化函數*/
int GetUseSize(float miu,float sigma); /*獲得請求尺寸*/
MMB *SelectUsedMem(int n);/*選擇待釋放的塊*/
void AddToUsed();/*將申請到的空閑分區加到分配分區鏈表中*/
int RequestMemff(int usize); /*請求分配指定大小的內存,首次適應演算法*/
int RequestMemnf(int usize); /*請求分配指定大小的內存,循環首次適應演算法*/
void AddToIdle();/*將被釋放的分配分區加到空閑分區鏈表中(按地址大小)*/
void ReleaseMem(); /*釋放指定的分配內存塊*/
/*主函數*/
void main()
{
int sim_step;
float miu,sigma; /*使隨機生成的請求尺寸符合正態分布的參數*/
int i;
int a;
MMB *p;
/* double TotalStep=0,TotalSize=0,TotalRatio=0,TotalUSize=0,Ratio=0,n=0;
double aveStep=0,aveSize=0,aveRatio=0;
int step=0,usesize=0; */
textcolor(11);
printf("\n\t\t內存管理模擬程序\n\n");
/* InitMem();*/
while(true)
{
double TotalStep=0,TotalSize=0,TotalRatio=0,TotalUSize=0,Ratio=0,n=0;
double aveStep=0,aveSize=0,aveRatio=0;
int step=0,usesize=0;
InitMem();
textcolor(12);
printf("\n\n首次適應演算法: 0");
printf("\n循環首次適應演算法: 1\n");
textcolor(11);
printf("\n請選擇一種演算法:");
scanf("%d",&a);
textcolor(15);
printf("\n輸入一定數量的步數:(sim_step)");
scanf("%d",&sim_step);
printf("\n 輸入使隨機生成的請求尺寸符合正態分布的參數:miu,sigma ");
scanf("%f,%f",&miu,&sigma);
for(i=1;i<=sim_step;i++)
{
textcolor(10);
printf("\n\n#[%d]\n",i);
do{
usesize=GetUseSize(miu,sigma);
while((usesize<0)||(usesize>TotalMemSize))
{
usesize=GetUseSize(miu,sigma);
}
textcolor(13);
printf("\n\n申請的內存尺寸為:%d",usesize);
printf("\n此時可用的空閑分區有 %d 塊情況如下:",idleNum);
p=idleHead;
textcolor(15);
while(p!=NULL)
{
printf("\n始址:%d\t 尺寸:%d",p->stAddr,p->memSize);
p=p->next;
}
TotalSize+=usesize;
if(a==0)
step=RequestMemff(usesize);
else
step=RequestMemnf(usesize);
TotalStep+=step;
n++;
}while(flag==1);
p=usedHead;
while(p!=NULL)
{
TotalUSize+=p->memSize;
printf("\n始址:%d\t 尺寸:%d",p->stAddr,p->memSize);
p=p->next;
}
textcolor(11);
if(TotalUSize!=0)
{
Ratio=TotalUSize/TotalMemSize;
TotalUSize=0;
printf("\n內存利用率NO.%d :%f%c",i,100*Ratio,'%');
}
else
{
Ratio=0;
printf("\n內存利用率NO.%d :%c%c",i,'0','%');
}
TotalRatio+=Ratio;
ReleaseMem();
}
if(n!=0)
{
textcolor(10);
aveStep=TotalStep/n;
aveSize=TotalSize/n;
aveRatio=TotalRatio/sim_step;
printf("\n平均搜索步驟:%f",aveStep);
printf("\n平均請求尺寸:%f",aveSize);
printf("\n平均內存利用率:%f",aveRatio);
}
}
}
// 輸出著色 /////////////////////////////////////////
void textcolor (int color)
{
SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), color );
}
/******************************
函數名:InitMem()
用途:把內存初始化為一整塊空閑塊
****************************************/
void InitMem()
{
MMB *p;
p=getpch(MMB);
p->memSize=TotalMemSize;
p->stAddr=0;
p->status=0;
p->next=NULL;
idleHead=p;
np=idleHead;
usedHead=NULL;
usedRear=NULL;
idleNum=1;
usedNum=0;
flag=1;
memIdle=NULL;
memUsed=NULL;
}
/******************************
函數名:GetUseSize(float miu,float sigma)
用途:獲得請求尺寸;
參數說明:float miu,float sigma :正態分布的參數
返回值:申請尺寸的大小;
****************************************************/
int GetUseSize(float miu,float sigma)
{
float r1,r2;
float u,v,w;
float x,y;
do
{
r1=rand()/32767.0;
r2=rand()/32767.0;
u=2*r1-1;
v=2*r2-1;
w=u*u+v*v;
}while(w>1);
x=u*sqrt(((-log(w))/w));
y=v*sqrt(((-log(w))/w));
return miu+sigma*x;
}
/******************************
函數名:*SelectUsedMem(int n)
用途:選擇待釋放的塊(0~n-1)
返回值:指向待釋放的塊的指針;
****************************************************/
MMB *SelectUsedMem(int n)
{
MMB *p;
int i,j;
if(n>0)
{
i = rand()%n ;
textcolor(5);
printf("\n\n當前已分配分區總數為:%d",n);
printf("\n待釋放塊的序號為:%d\n",i );
p=usedHead;
if(p!=NULL)
{
for(j=i;j>0;j--)
p=p->next;
return(p);
}
else
return(NULL);
}
else
{
printf("\n當前沒有可釋放的資源!\n");
}
}
/******************************
函數名:AddToUsed()
用途:將申請到的空閑分區加到分配分區鏈表中
***************************************************************/
void AddToUsed()
{
MMB *p;
memIdle->status=1;
if(usedHead==NULL)
{
usedHead=memIdle;
usedRear=usedHead;
}
else
{
usedRear->next=memIdle;
usedRear=memIdle;
}
usedNum++;
printf("\n當前分配分區共有%d塊!",usedNum);
p=usedHead;
while(p!=NULL)
{
printf("\n始址:%d \t 尺寸:%d",p->stAddr,p->memSize);
p=p->next;
}
}
/******************************
函數名:RequestMemff(int usize)
參數說明:usize:請求尺寸的大小;
用途:請求分配指定大小的內存,首次適應演算法
返回值:搜索步驟
***************************************************************/
int RequestMemff(int usize)
{
MMB *p1,*p2,*s;
int step;
int suc=0;
int size1,size2;
if(idleHead==NULL)
{
flag=0;
textcolor(12);
printf("\n分配失敗!");
return 0;
}
else
{
if((idleHead->memSize)>usize)
{
size1=(idleHead->memSize)-usize;
if(size1<=MinSize)
{
memIdle=idleHead;
idleHead=idleHead->next;
memIdle->next=NULL;
idleNum--;
}
else
{
s=getpch(MMB);
s->memSize=usize;
s->stAddr=idleHead->stAddr;
s->status=1;
s->next=NULL;
memIdle=s;
idleHead->memSize=idleHead->memSize-usize;
idleHead->stAddr=idleHead->stAddr+usize;
}
step=1;
flag=1;
textcolor(12);
printf("\n分配成功!");
AddToUsed();
}
else
{
p1=idleHead;
step=1;
p2=p1->next;
while(p2!=NULL)
{
if((p2->memSize)>usize)
{
size2=(p2->memSize)-usize;
if(size2<=MinSize)
{
p1->next=p2->next;
memIdle=p2;
memIdle->next=NULL;
idleNum--;
}
else
{
s=getpch(MMB);
s->memSize=usize;
s->stAddr=p2->stAddr;
s->status=1;
s->next=NULL;
memIdle=s;
p2->memSize=p2->memSize-usize;
p2->stAddr=p2->stAddr+usize;
}
flag=1;
suc=1;
textcolor(12);
printf("\n分配成功!");
AddToUsed();
p2=NULL;
}
else
{
p1=p1->next;
p2=p2->next;
step++;
}
}
if(suc==0)
{
flag=0;
textcolor(12);
printf("\n分配失敗!");
}
}
}
return step;
}
/******************************
函數名:AddToIdle()
用途:將被釋放的分配分區加到空閑分區鏈表中(按地址遞增順序排列)
***************************************************************/
void AddToIdle()
{
MMB *p1,*p2;
int insert=0;
if((idleHead==NULL))
{
idleHead=memUsed;
idleNum++;
np=idleHead;
}
else
{
int Add=(memUsed->stAddr)+(memUsed->memSize);
if((memUsed->stAddr<idleHead->stAddr)&&(Add!=idleHead->stAddr))
{
memUsed->next=idleHead;
idleHead=memUsed;
idleNum++;
}
else
{
if((memUsed->stAddr<idleHead->stAddr)&&(Add==idleHead->stAddr))
{
idleHead->stAddr=memUsed->stAddr;
idleHead->memSize+=memUsed->memSize;
}
else
{
p1=idleHead;
p2=p1->next;
while(p2!=NULL)
{
if(memUsed->stAddr>p2->stAddr)
{
p1=p1->next;
p2=p2->next;
}
else
{
int Add1=p1->stAddr+p1->memSize;
int Add2=p2->stAddr-memUsed->memSize;
if((Add1==memUsed->stAddr)&&(memUsed->stAddr!=Add2))
{
p1->memSize=p1->memSize+memUsed->memSize;
}
if((Add1!=memUsed->stAddr)&&(memUsed->stAddr==Add2))
{
p2->memSize=p2->memSize+memUsed->memSize;
p2->stAddr=memUsed->stAddr;
}
if((Add1!=memUsed->stAddr)&&(memUsed->stAddr!=Add2))
{
memUsed->next=p2;
p1->next=memUsed;
if(np->stAddr==p2->stAddr)
np=p1->next;
idleNum++;
}
if((Add1==memUsed->stAddr)&&(memUsed->stAddr==Add2))
{
p1->memSize=p1->memSize+memUsed->memSize+p2->memSize;
p1->next=p2->next;
if((np->stAddr)==(p2->stAddr))
np=p1;
idleNum--;
}
p2=NULL;
insert=1;
}
}
if(insert==0)
{
p1->next=memUsed;
idleNum++;
}
}
}
}
}
/******************************
函數名:ReleaseMem()
用途:釋放指定的分配內存塊
***************************************************************/
void ReleaseMem()
{
MMB *q1,*q2;
MMB *s;
if(usedNum==0)
{
printf("\n當前沒有分配分區!");
return;
}
else
{
s=SelectUsedMem(usedNum);
if(s!=NULL)
{
if(s->stAddr==usedHead->stAddr)
{
memUsed=usedHead;
usedHead=usedHead->next;
memUsed->next=NULL;
AddToIdle();
usedNum--;
}
else
{
q1=usedHead;
q2=q1->next;
while(q2!=NULL)
{
if(q2->stAddr!=s->stAddr)
{
q1=q1->next;
q2=q2->next;
}
else
{
q1->next=q2->next;
memUsed=q2;
memUsed->next=NULL;
if(q1->next==NULL)
usedRear=q1;
AddToIdle();
usedNum--;
q2=NULL;
}
}
}
}
}
}
/******************************
函數名:RequestMemnf(int usize)
參數說明:usize:請求尺寸的大小;
用途:請求分配指定大小的內存,循環首次適應演算法
返回值:搜索步驟
***************************************************************/
int RequestMemnf(int usize)
{
MMB *p2,*p,*s;
int step;
int iNum=0;
int suc=0;
int size1,size2,size3;
if(idleHead==NULL)
{
flag=0;
printf("\n分配失敗!");
return 0;
}
else
{
iNum=idleNum;
while(iNum>0)
{
iNum--;
if((np->memSize)>usize)
{
/*指針指向的空閑塊滿足條件,且正好為頭指針*/
if(np->stAddr==idleHead->stAddr)
{
size1=(idleHead->memSize)-usize;
if(size1<=MinSize)
{
memIdle=idleHead;
idleHead=idleHead->next;
memIdle->next=NULL;
idleNum--;
}
else
{
s=getpch(MMB);
s->memSize=usize;
s->stAddr=idleHead->stAddr;
s->status=1;
s->next=NULL;
memIdle=s;
idleHead->memSize=idleHead->memSize-usize;
idleHead->stAddr=idleHead->stAddr+usize;
}
if((idleHead==NULL)||(idleHead->next==NULL))
np=idleHead;
else
np=idleHead->next;
}
else/*指針指向的空閑塊滿足條件,不為頭指針*/
{
size2=(np->memSize)-usize;
if(size2<=MinSize) /*從空閑鏈表中刪除*/
{
p=idleHead;
while(p->next->stAddr!=np->stAddr)
p=p->next;
p->next=np->next;
memIdle=np;
memIdle->next=NULL;
np=p;
idleNum--;
}
else
{
s=getpch(MMB);
s->memSize=usize;
s->stAddr=np->stAddr;
s->status=1;
s->next=NULL;
memIdle=s;
np->memSize=np->memSize-usize;
np->stAddr=np->stAddr+usize;
}
if(np->next==NULL)
np=idleHead;
else
np=np->next;
}
step=1;
flag=1;
suc=1;
textcolor(12);
printf("\n分配成功!");
AddToUsed();
iNum=0;
}
else /*當前指針指向的空閑區不滿足條件*/
{
step=1;
p2=np->next;
if(p2==NULL)
{
np=idleHead;
iNum--;
}
else
{
if((p2->memSize)>usize)
{
size3=(p2->memSize)-usize;
if(size3<=MinSize)
{
np->next=p2->next;
memIdle=p2;
memIdle->next=NULL;
idleNum--;
}
else
{
s=getpch(MMB);
s->memSize=usize;
s->stAddr=p2->stAddr;
s->status=1;
s->next=NULL;
memIdle=s;
p2->memSize=p2->memSize-usize;
p2->stAddr=p2->stAddr+usize;
}
flag=1;
suc=1;
printf("\n分配成功!");
AddToUsed();
if(p2->next==NULL)
np=idleHead;
else
np=p2->next;
p2=NULL;
iNum=0;
}
else
{
np=np->next;
p2=p2->next;
iNum--;
step++;
}
}
}
// iNum--;
}
if(suc==0)
{
flag=0;
textcolor(12);
printf("\n分配失敗!");
}
}
return step;
}
⑧ 採用c語言實現首次適應演算法完成主存空間的分配和回收 急
有沒有具體的要求,比方說數據結構方面,我這有一個,你可以參考參考
#include"stdio.h"
#include"stdlib.h"
#define
n
10
/*假定系統允許的最大作業為n,假定模擬實驗中n值為10*/
#define
m
10
/*假定系統允許的空閑區表最大為m,假定模擬實驗中m值為10*/
#define
minisize
100
struct{
float
address;
/*已分分區起始地址*/
float
length;
/*已分分區長度,單位為位元組*/
int
flag;
/*已分配區表登記欄標志,用"0"表示空欄目*/
}used_table[n];
/*已分配區表*/
struct{
float
address;
/*空閑區起始地址*/
float
length;
/*空閑區長度,單位為位元組*/
int
flag;
/*空閑區表登記欄標志,用"0"表示空欄目,用"1"表示未分配*/
}free_table[m];
/*空閑區表*/
void
main(
)
{
int
i,a;
void
allocate(char
str,float
leg);//分配主存空間函數
void
reclaim(char
str);//回收主存函數
float
xk;
char
J;/*空閑分區表初始化:*/
free_table[0].address=10240;
free_table[0].length=102400;
free_table[0].flag=1;
for(i=1;i<m;i++)
free_table[i].flag=0;/*已分配表初始化:*/
for(i=0;i<n;i++)
used_table[i].flag=0;
while(1)
{
printf("\n選擇功能項(0-退出,1-分配主存,2-回收主存,3-顯示主存)\n");
printf("選擇功項(0~3)
:");
scanf("%d",&a);
switch(a)
{
case
0:
exit(0);
/*a=0程序結束*/
case
1:
/*a=1分配主存空間*/printf("輸入作業名J和作業所需長度xk:
");
scanf("%*c%c%f",&J,&xk);
allocate(J,xk);/*分配主存空間*/
break;
case
2:
/*a=2回收主存空間*/printf("輸入要回收分區的作業名");
scanf("%*c%c",&J);reclaim(J);/*回收主存空間*/
break;
case
3:
/*a=3顯示主存情況*//*輸出空閑區表和已分配表的內容*/
printf("輸出空閑區表:\n起始地址
分區長度
標志\n");
for(i=0;i<m;i++)
printf("%6.0f%9.0f%6d\n",free_table[i].address,free_table[i].length,
free_table[i].flag);
printf("
按任意鍵,輸出已分配區表\n");
getchar();
printf("
輸出已分配區表:\n起始地址
分區長度
標志\n");
for(i=0;i<n;i++)
if(used_table[i].flag!=0)
printf("%6.0f%9.0f%6c\n",used_table[i].address,used_table[i].length,
used_table[i].flag);
else
printf("%6.0f%9.0f%6d\n",used_table[i].address,used_table[i].length,
used_table[i].flag);
break;
default:printf("沒有該選項\n");
}/*case*/
}/*while*/
}/*主函數結束*/
int
uflag;//分配表標志
int
fflag;//空閑表標志
float
uend_address;
float
fend_address;
void
allocate(char
str,float
leg)
{
uflag=0;fflag=0;
int
k,i;float
ressize;
for(i=0;i<m;i++)
{
if(free_table[i].flag==1
&&
free_table[i].length>=leg)
{
fflag=1;break;
}
}
if(fflag==0)
printf("沒有滿足條件的空閑區\n");
else
{
ressize=free_table[i].length-leg;
for(k=0;k<n;k++)
{
if(used_table[k].flag==0)
{
if(ressize<minisize)//剩餘塊過小
{
used_table[k].length=free_table[i].length;
used_table[k].address=free_table[i].address;
used_table[k].flag=str;
free_table[i].length=0;
free_table[i].flag=0;
break;
}
else
{
used_table[k].address=free_table[i].address+ressize;
used_table[k].flag=str;
used_table[k].length=leg;
free_table[i].length=ressize;
break;
}
}
}//for結束
}
}
void
reclaim(char
str)
{
uflag=0;fflag=0;
int
k,i;
for(k=0;k<n;k++)
{
if(used_table[k].flag==str)
{
uflag=1;break;
}
}
if(uflag==0)
printf("\n找不到該作業!\n");
else
{
for(i=0;i<m;i++)
{
uend_address=used_table[k].address+used_table[k].length;
fend_address=free_table[i].address+free_table[i].length;
if(used_table[k].address==fend_address)//上鄰
{
fflag=1;
free_table[i].length=free_table[i].length+used_table[k].length;
free_table[i].flag=1;
used_table[k].flag=0;
used_table[k].length=0;
used_table[k].address=0;
printf("\n已回收!\n");
break;
}
else
{
if(free_table[i].address==uend_address)//下鄰
{
fflag=1;
free_table[i].address=used_table[k].address;
free_table[i].length=free_table[i].length+used_table[k].length;
free_table[i].flag=1;
used_table[k].flag=0;
used_table[k].length=0;
used_table[k].address=0;
printf("\n已回收!\n");
break;
}
}
}//for結束
if(fflag==0)
{
i=0;
for(i=0;i<m;i++)
{
if(free_table[i].flag==0)
{
free_table[i].address=used_table[k].address;
free_table[i].length=used_table[k].length;
free_table[i].flag=1;
used_table[k].length=0;
used_table[k].flag=0;
used_table[k].address=0;
break;
}
}
printf("\n已回收!\n");
}
}
}