儲存管理動態分區分配及回收演算法

來源:互聯網
上載者:User

實驗環境:C/C++
一、目的和要求
分區管理是應用較廣泛的一種儲存管理技術。本實驗要求用一種結構化進階語言構造分區描述器,
編製動態分區分配演算法和回收演算法類比程式,並討論不同分配演算法的特點。

二、實驗內容
1、編寫:First Fit Algorithm
2、編寫:Best Fit Algorithm
3、編寫:空閑區回收演算法

三、提示和說明
(一)主程式
1、定義分區描述器node,包括 3個元素:
(1)adr--分區首地址
(2)size--分區大小
(3)next--指向下一個分區的指標
2、定義 3個指向node結構的指標變數:
(1)head1--空閑區隊列首指標
(2)back1--指向釋放區node結構的指標
(3)assign--指向申請的記憶體分區node結構的指標
3、定義 1個整形變數:
free--使用者申請儲存區的大小(由使用者鍵入)
(二)過程
1、定義check過程,用於檢查指定的釋放塊(由使用者鍵入)的合法性
2、定義assignment1過程,實現First Fit Algorithm
3、定義assignment2過程,實現Best Fit Algorithm
4、定義acceptment1過程,實現First Fit Algorithm的回收演算法
5、定義acceptment2過程,實現Best Fit Algorithm的回收演算法
6、定義print過程,列印空閑區隊列
(三)執行
程式首先申請一整塊空閑區,其首址為0,大小為32767;然後,提示使用者使用哪種分配演算法,
再提示是分配還是回收;分配時要求輸入申請區的大小,回收時要求輸入釋放區的首址和大小。
(四)輸出   
要求每執行一次,輸出一次空閑區隊列情況,內容包括:
編號  首址  終址  大小
註:輸出空閑區隊列的排序,應符合所用分配演算法的要求。

#include <stdio.h><br />#include <stdlib.h><br />#include <string.h><br />/* ==========宏定義部分========== */<br />#define FootLoc(p) (p+p->size-1)// 指向p所指結點的底部<br />#define MINSIZE 10 // 空閑地區最小的底限<br />#define INITSIZE 500 // 初始化儲存空間的大小<br />#define Status int // 返回狀態<br />#define OK 1 // 正確傳回值<br />#define ERROR 0 // 錯誤返回<br />#define NUM 20 // 記憶體最大個數<br />/* ==========結構定義部分========== */<br />typedef struct WORD // 記憶體字類型<br />{<br /> union // head和foot分別是結點的第一個字和最後一個字<br /> {<br /> WORD *link; // 頭部域,指向前趨結點<br /> WORD *uplink; // 底部域,指向本結點頭部<br /> };<br /> int tag; // 塊標誌,0:空閑,1:佔用,頭部和尾部均有<br /> int size; // 頭部域,塊大小<br /> WORD *rlink; // 頭部域,指向後繼結點<br /> // char flag[10];<br />}WORD,head,foot,*Space; // *Space:可利用空間指標類型<br />typedef struct ProcInf // 分配的進程資訊<br />{<br /> Space Sp_Head; // 進程分配到的記憶體位址<br /> char name[15]; // 進程描述標識<br /> struct ProcInf *next; // 鏈表指標<br />}ProcInf;<br />/* =============函式宣告部分============ */<br />Space InitMem( int n );<br />Space AllocBoundTag( WORD *pav, int n );<br />Status RecycleAlg(Space p,Space pav);<br />Space DuSort( WORD *pav );<br />void Insert(WORD *pav,WORD *p);<br />Space DelNode(ProcInf *h,char id[15]);<br />Status InsertProInf(ProcInf *h, Space inser, char id[15]);<br />int main(int argc, char* argv[])<br />{<br /> WORD *p,*Ret_Proc_Add,*Rec; // p存放申請記憶體位址的頭指標<br /> ProcInf *pi_h = NULL; // 運行進程鏈表頭指標<br /> int i;<br /> int Num;<br /> int size;<br /> int n = INITSIZE;<br /> char id[15]; // 存放進程標識<br /> pi_h= (ProcInf *)malloc(sizeof(ProcInf)); // 初始化運行進程鏈表頭結點<br /> pi_h ->next =NULL;<br /> p = InitMem(n); // 初始化申請的記憶體空間,剛開始為一整塊空白記憶體大小為n<br /> if(!p) // 判斷是否申請成功,失敗結束運行<br /> {<br /> printf("記憶體初始化失敗!/n");<br /> exit(1);<br /> }<br /> //測試案例<br /> // 輸入要建立進程的個數<br /> printf("要申請的空間個數及其每一個空間所需要的儲存空間:/n");<br /> scanf("%d",&Num);<br /> for( i = 0; i < Num; i++ )<br /> {<br />L: printf("第%d個空間的儲存空間和空間的ID:",i+1);<br /> scanf("%d%s",&size,id);<br /> getchar(); // 吸收斷行符號符號<br /> Ret_Proc_Add = AllocBoundTag( p, size );// 記憶體配置大小為size<br /> if(!Ret_Proc_Add) // 判斷記憶體是否分配成功<br /> {<br /> printf("記憶體可能不足,分配失敗,重新輸入./n");<br /> goto L;<br /> }<br /> InsertProInf(pi_h,Ret_Proc_Add,id); // 插入到已經分配的記憶體鏈表當中<br /> printf("分配記憶體標識:%s,首地址:0x%x,大小:%d/n",id,Ret_Proc_Add,Ret_Proc_Add ->size);<br /> }<br /> for( i = 0; i < Num; i++ )<br /> {<br /> printf("輸入要回收結點的名字:");<br /> scanf("%s",id);<br /> getchar();<br /> Rec = DelNode(pi_h,id);<br /> if(!Rec)<br /> {<br /> printf("輸入結點無效,請重新輸入./n");<br /> --i;<br /> }<br /> else<br /> RecycleAlg(Rec,p);<br /> }<br /> getchar();<br /> return 0;<br />}<br />Space DelNode(ProcInf *h,char id[15])<br />{<br /> ProcInf *t,*p;<br /> p = h ->next;<br /> t = h;<br /> if( !p )<br /> {<br /> printf("此空間不存在!/n");<br /> return NULL;<br /> }<br /> while(p ->next!=NULL && strcmp(id,p->name))<br /> {<br /> t = p;<br /> p = p->next;<br /> }<br /> if( p ->next!=NULL )<br /> {<br /> t ->next = p->next;<br /> return p ->Sp_Head;<br /> }<br /> else if(!strcmp(id,p->name))<br /> {<br /> t ->next = p ->next;<br /> return p->Sp_Head;<br /> }<br /> else<br /> {<br /> printf("此空間不存在!/n");<br /> return NULL;<br /> }<br />}<br />Status InsertProInf(ProcInf *h,Space inser,char id[15])<br />{<br /> ProcInf *t,*p;<br /> p = h->next;<br /> if( h->next == NULL )<br /> {<br /> if(!(t = (ProcInf *)malloc(sizeof(ProcInf))))<br /> return ERROR;<br /> t ->Sp_Head = inser;<br /> strcpy( t ->name,id);<br /> t ->next = NULL;<br /> p = t;<br /> h ->next = p;<br /> return OK;<br /> }<br /> else<br /> {<br /> if(!(t = (ProcInf *)malloc(sizeof(ProcInf))))<br /> return ERROR;<br /> t ->Sp_Head = inser;<br /> strcpy( t ->name,id);<br /> t ->next = NULL;<br /> while(p->next)<br /> p = p->next;<br /> p ->next = t;<br /> return OK;<br /> }<br />}<br />Space InitMem( int n ) // 初始化分配可利用記憶體的大小<br />{<br /> Space p;<br /> p = (Space)malloc(n*sizeof(WORD));<br /> if( p )<br /> {<br /> p ->tag = 0; // 設定使用標誌為:未使用<br /> p ->size = n; // 設定大小<br /> p ->rlink = p ->link = p;// 初始化指標<br /> p ->uplink = p; //指向本身<br /> return p;<br /> }<br /> else<br /> return ERROR; // 分配失敗<br />}<br />Space AllocBoundTag( WORD *pav, int n ) // 若有不小於n的空閑塊,則分配相應的存<br />{ // 儲塊,並返回其首地址;否則返回空,若<br /> Space p,f; // 分配後可利用空間表不空,則pav指向表中剛分配過的結點的後繼結點。<br /> // 尋找不小於n的空閑塊<br /> for( p = pav; p && p->size < n && p->rlink != pav; p = p->rlink );<br /> if( !p || p->size < n )<br /> return NULL; // 尋找失敗返回null 指標<br /> else // p指向找到的空閑塊<br /> {<br /> f = FootLoc(p); // f指向此空閑塊的底部<br /> pav = p->rlink; // pav指向*p結點的後繼結點<br /> if( p->size-n <= MINSIZE ) // 整塊分配,不保留<=MINSIZE的剩餘量<br /> {<br /> if( pav == p ) // 如果可利用空間表變為空白表,則置pav為空白<br /> pav=NULL;<br /> else<br /> { // 在表中刪除分配的結點<br /> pav->link = p->link;<br /> p->link->rlink=pav;<br /> }<br /> p->tag = f->tag = 1;// 修改分配節點的頭部和底部的標誌<br /> }<br /> else // 分配該塊的後n個字<br /> {<br /> f->tag = 1; // 修改分配塊的底部標誌<br /> p->size -= n; // 置剩餘塊的大小<br /> f = FootLoc(p); // 指向剩餘塊的底部<br /> f->tag = 0;f->uplink = p;//設定剩餘塊的底部<br /> p = f + 1; // 指向分配塊的頭部<br /> p->tag = 1; // 設定分配塊頭部<br /> p->size = n; // 設定分配塊的大小<br /> }<br /> return p; // 返回分配塊首地址<br /> }<br />}<br />Status RecycleAlg(Space p,Space pav) // 回收演算法<br />{<br /> Space f,q,ql,t,s;<br /> int n;<br /> if( (p-1)->tag != 0 && (p+p->size)->tag != 0 )<br /> {<br /> // 釋放塊的左右鄰區均為佔用塊<br /> printf("釋放塊的左右鄰區均為佔用塊./n");<br /> p -> tag = 0;<br /> FootLoc(p) ->uplink = p;<br /> FootLoc(p) ->tag = 0;<br /> if( !pav )<br /> pav = p ->link = p ->rlink = p;<br /> else<br /> {<br /> q = pav ->link;<br /> p ->rlink = pav;<br /> p ->link = q;<br /> q ->rlink = pav ->link = p;<br /> pav = p; // 令剛釋放的結點為下次分配時的最先查詢結點<br /> }<br /> }<br /> if((p-1)->tag == 0 && (p+p->size)->tag != 0)<br /> {<br /> // 釋放塊左鄰區為空白閑塊<br /> printf("釋放塊左鄰區為空白閑塊./n");<br /> n = p ->size; // 釋放塊的大小<br /> s = (p-1)->uplink; // 左空閑塊的的頭部地址<br /> s ->size += n; // 設定新的空閑塊的大小<br /> f = p + n - 1; // 設定新的空閑塊的底部<br /> f ->uplink = s;<br /> f ->tag = 0;<br /> }<br /> if( (p+p->size)->tag==0 && (p-1)->tag != 0 )<br /> {<br /> //釋放塊的右鄰區為空白閑塊<br /> printf("釋放塊的右鄰區為空白閑塊./n");<br /> t = p + p ->size; // 右鄰空閑塊的頭部地址<br /> p ->tag = 0; // p為合并後的結點頭部地址<br /> q =t ->link;<br /> p ->link = q;<br /> q ->rlink = p;<br /> ql = t ->rlink;<br /> p ->rlink = ql;<br /> ql ->link = p;<br /> p ->size += t->size;<br /> FootLoc(t) -> uplink = p;<br /> }<br /> if((p-1)->tag == 0 && (p+p->size)->tag == 0)<br /> {<br /> // 釋放塊的左右鄰塊均為空白閑塊<br /> printf("釋放塊的左右鄰塊均為空白閑塊./n");<br /> n = p->size;<br /> s = (p-1)->uplink;<br /> t = p+p->size;<br /> s ->size += n + t ->size;<br /> q = t ->link;<br /> ql = t ->rlink;<br /> q ->rlink = ql;<br /> ql ->link = q;<br /> FootLoc(t) ->uplink = s;<br /> }<br /> return 0;<br />}<br />Space DuSort( WORD *pav ) // 雙鏈表排序<br />{<br /> Space p,q;<br /> p = NULL;<br /> q = pav ->rlink;<br /> if(!pav) return NULL; // 如果為空白鏈表,則返回空<br /> while(q -> rlink != q->link) //<br /> {<br /> pav->link->rlink = pav->rlink;<br /> pav->rlink->link = pav->link;<br /> Insert(p,pav);<br /> pav = q;<br /> q = q->rlink;<br /> }<br /> Insert(p,q); // 將最後一個結點插入<br /> return p;<br />}<br />void Insert(WORD *pav,WORD *p) // 插入排序,按照可用大小從小到大<br />{<br /> WORD *t;<br /> t = pav;<br /> if(!pav)<br /> {<br /> pav = p;<br /> pav ->rlink = pav ->link;<br /> }<br /> else<br /> {<br /> while(t->size<p->size)<br /> {<br /> t = t->rlink;<br /> }<br /> p ->rlink =t;<br /> p ->link = t->link;<br /> t ->link->rlink = p;<br /> t ->link = p;<br /> }<br />}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.