- 袁禕琦
- 201821121033
- 計算1812
內存管理的功能:
1、內存空間的分配與回收:由操作系統完成主存儲器空間的分配和管理,使程序員擺脫存儲分配的麻煩,提高編程效率。
2、地址轉換:在多道程序環境下,程序中的邏輯地址與內存中的物理地址不可能一致,因此存儲管理必須提供地址轉換功能,把邏輯地址轉換成相應的物理地址。
3、內存空間的擴充:利用虛擬內存技術或自動覆蓋技術,從邏輯上擴充內存。
4、存儲保護:保證各道作業在各自的存儲空間內運行,互不干擾。
1. 記錄內存空間使用情況
所謂分區,就是分為一些大小相等或不等的分區,除操作系統占用一個分區外,其余分區用來存放進程的程序和數據,本次實驗中采用動態分區法。
操作系統對內存的划分和動態分配,就是內存管理的概念。有效的內存管理在多道程序設計中非常重要,不僅方便用戶使用存儲器、提高內存利用率,還可以通過虛擬技術從邏輯上擴充存儲器。
1 int display_mem_usage(){ 2 //顯示當前內存的使用情況,包括空閑分區的情況和已經分配的情況 3 FBT *fbt = free_block; 4 AB *ab = allocated_block_head; 5 printf("\e[0;31;1m------------------------------------------------------------------\e[0m\n"); 6 //顯示空閑區 7 printf("\e[0;32;1mFree Memory:\e[0m\n"); 8 printf("\e[0;33;1m%20s %20s\e[0m\n"," start_addr"," size"); 9 while(fbt!=NULL){ 10 printf("%20d %20d\n",fbt->start_addr,fbt->size); 11 fbt = fbt->next; 12 } 13 //顯示已分配區 14 printf("\n"); 15 printf("\e[0;35;1mUsed Memory:\e[0m\n"); 16 printf("\e[0;33;1m%10s %20s %20s %10s\e[0m\n","PID","ProcessName","start_addr","size"); 17 while(ab != NULL){ 18 printf("%10d %20s %20d %10d\n",ab->pid,ab->process_name,ab->start_addr,ab->size); 19 ab = ab->next; 20 } 21 printf("\e[0;31;1m------------------------------------------------------------------\e[0m\n"); 22 return 0; 23 }
2. 記錄空閑分區
空閑內存區塊表,包含該空閑區的起始地址以及大小。建立空閑分區鏈表,使之指向內存中空閑塊鏈的首指針。
//描述每一個空閑塊的數據結構 typedef struct free_block_type{ int size; int start_addr; struct free_block_type *next; }FBT; //每個進程分配到的內存塊描述 typedef struct allocated_block{ int pid; int size; int start_addr; char process_name[PROCESS_NAME_LEN]; struct allocated_block *next; }AB; //指向內存中空閑塊鏈表的首指針 FBT *free_block; //進程分配內存塊鏈表的首指針 AB *allocated_block_head = NULL; //初始化空閑分區鏈表 FBT *init_free_block(int mem_size){ FBT *fb;//申請空間 fb = (FBT*)malloc(sizeof(FBT)); if(fb==NULL){ printf("No mem\n"); return NULL; } fb->size = mem_size; fb->start_addr = DEFAULT_MEM_START; fb->next = NULL; return fb; }
空閑分區(free_block_type)結構體解釋:size屬性表示空閑分區的大小,start_addr表示空閑 分區首地址,next指針指向下一個空閑分區。
已分配內存空間(allocated_block)結構體解釋:定義已分配的內存空間的機構提,用來保存已經被進程占用了內存空間的情況。其中,pid作為該被分配分區的編號,用於在釋放該內存看空間時便於查找。size表示的分區的大小,start_addr表示分區的起始地址,process_name存放進程名稱,next指針指向下一個分區。
3. 內存分配算法
內存分配算法:首先從可用表/自由鏈中找到一個足以容納該作業的可用空白區,如果這個空白區比需求大,則將它分為兩個部分,一部分稱為已分配去,剩下部分仍為空閑區。最后修改可用表或自由鏈,並回送一個所分配區的序號或該分配區的起始地址。其余的在下面的代碼區塊中有解釋。
內存分配過程(解釋在代碼中):
1 //設置內存大小 2 int set_mem_size(){ 3 int size; 4 if(flag!=0){ 5 printf("Cannot set memory size again\n"); 6 return 0; 7 } 8 printf("Total memory size ="); 9 scanf("%d",&size); 10 if(size>0){ 11 mem_size = size; 12 free_block->size = mem_size; 13 } 14 flag = 1; 15 min_mem_size = mem_size / 100; 16 return 1; 17 } 18 19 //設置分配算法 20 void set_algorithm(){ 21 int algorithm; 22 printf("\t1 - First Fit\n"); 23 printf("\t2 - Best Fit\n"); 24 printf("\t3 - Worst Fit\n"); 25 scanf("%d",&algorithm); 26 if(algorithm>=1 && algorithm<=3) 27 ma_algorithm = algorithm; 28 //按指定算法重新排列空閑區鏈表 29 rearrange(ma_algorithm); 30 } 31 32 //進行內存緊縮 33 void memory_compact(){ 34 FBT *fbttmp = free_block; 35 AB *abtmp = allocated_block_head; 36 //檢測剩余內存 37 int sum = 0; 38 while(fbttmp!=NULL){ 39 sum += fbttmp->size; 40 fbttmp = fbttmp->next; 41 } 42 //合並區塊為一個 43 fbttmp = free_block; 44 fbttmp->size = sum; 45 fbttmp->start_addr = 0; 46 fbttmp->next=NULL; 47 //釋放多余分區 48 FBT *pr = free_block->next; 49 while(pr != NULL){ 50 fbttmp = pr->next; 51 free(pr); 52 pr = fbttmp; 53 } 54 //重新排序已分配空間 55 sort_AB(); 56 reset_AB(sum); 57 } 58 59 //分配內存模塊 60 int allocate_mem(AB *ab){ 61 FBT *fbt,*pre; 62 int request_size=ab->size; 63 fbt = pre = free_block; 64 //嘗試尋找可分配空閑,具體結果在函數中有解釋 65 int f = find_free_mem(request_size); 66 if(f == -1){ 67 //不夠分配 68 printf("Free mem is not enough,Allocate fail!\n"); 69 return -1; 70 }else{ 71 if(f == 0){ 72 //需要內存緊縮才能分配 73 memory_compact(); 74 } 75 //執行分配 76 do_allocate_mem(ab); 77 } 78 //重新排布空閑分區 79 rearrange(ma_algorithm); 80 return 1; 81 } 82 83 //執行分配內存模塊 84 void do_allocate_mem(AB *ab){ 85 int request = ab->size; 86 FBT *tmp = free_block; 87 while(tmp != NULL){ 88 if(tmp->size >= request){ 89 //分配 90 ab->start_addr = tmp->start_addr; 91 int shengyu = tmp->size - request; 92 if(shengyu <= min_mem_size){ 93 //剩余過小全部分配 94 ab->size = tmp->size; 95 if(tmp == free_block){ 96 free_block = free_block->next; 97 free(tmp); 98 }else{ 99 FBT *t = free_block; 100 while(t->next != tmp){ 101 t = t->next; 102 } 103 t->next = tmp->next; 104 free(tmp); 105 } 106 }else{ 107 //切割出分配走的內存 108 tmp->size = shengyu; 109 tmp->start_addr = tmp->start_addr + request; 110 } 111 return ; 112 } 113 tmp = tmp->next; 114 } 115 } 116 117 //創建新進程 118 int new_process(){ 119 AB *ab; 120 int size; 121 int ret; 122 ab = (AB*)malloc(sizeof(AB)); 123 if(!ab) exit(-5); 124 ab->next=NULL; 125 pid++; 126 sprintf(ab->process_name,"PROCESS-%02d",pid); 127 ab->pid = pid; 128 printf("Memory for %s:",ab->process_name); 129 scanf("%d",&size); 130 if(size>0) ab->size=size; 131 ret = allocate_mem(ab); //從空閑分區分配內存,ret==1表示分配成功 132 if((ret == 1) && (allocated_block_head == NULL)){ 133 //如果此時allocated_block_head尚未賦值,則賦值 134 allocated_block_head = ab; 135 return 1; 136 }else if(ret == 1){ 137 //分配成功,將該分配塊的描述插入已分配鏈表 138 ab->next = allocated_block_head; 139 allocated_block_head = ab; 140 return 2; 141 }else if(ret == -1){ //分配不成功 142 printf("\e[0;31;1m Allocation fail \e[0m\n"); 143 free(ab); 144 return -1; 145 } 146 return 3; 147 }
初始化模塊(allocate_mem):設置內存的最大容量,該內存空間的首地址,一遍之后新建進程的過程中使用,當空閑分區初始化失敗時,要進行相應的提示。
新建進程模塊(new_process):在內存空間中申請一塊空間供進程使用,通過輸入進程大小,系統先查看內次年空間中是否有足夠的空間供其進行申請,若無,則顯示分配失敗信息,否則在空閑內存分區塊中選擇最先的一塊進行分配,若內存空間不足則繼續向下查找,空閑內存分區的順序通過三種算法給出,分配內存時,要指定進程的首地址和大小,並對空閑分區的大小做相應的修改。
其中,set_algorithm中的算法包括:
1 //按指定的算法整理內存空閑塊鏈表 2 void rearrange(int algorithm){ 3 switch(algorithm){ 4 case MA_FF:rearrange_FF();break;//首次適應算法 5 case MA_BF:rearrange_BF();break;//最佳算法 6 case MA_WF:rearrange_WF();break;//最壞適應算法 7 } 8 }
三種內存分配算法的特點和不同:
/* 1、最先適應算法(FF) 它要求空閑分區表中的記錄按地址遞增的順序排列。在每次分配主存時,總是從第一條記錄開始順序查找空閑分區表,找到第一個能滿足作業長度要求的空閑區,分隔這個空閑區。一部分分配給作業,另一部分仍作為空閑區。 特點: 分配算法簡單,容易產生過多的主存碎片。主存碎片是指小的不能使用的主存空間;這種算法把大的空閑區分成了小的空閑區,當有大的作業要求分配時,不能滿足要求,降低了系統的效率。 2、最優適應算法(BF) 它是從所有的空閑分區中挑選一個能滿足作業要求的最小空閑區進行分配。這樣可以保證不去分割一個更大的空閑區,使裝入大作業時比較容易得到滿足。為實現這種算法,把空閑區按長度遞增次序登記在空閑分區表中,分配時,順序查找。 特點: 解決了大作業的分配問題,不足是容易產生主存碎片,降低了主存空間的利用率。另外,回收主存時,要按長度遞增順序插入到空閑分區表中,增加了系統開銷。 3、最壞適應分配算法(WF) 它每次分配主存時總是挑選一個最大的空閑區,分割一部分給作業使用,使剩下的部分不至於太小而成為主存碎片。為實現這種算法,把空閑區按長度遞減的次序登記在空閑分區表中,分配時,順序查找。 特點: 不會產生過多的碎片。不足是影響大作業的分配。回收主存時,要按長度遞減的順序插入到空閑分區表中,增加了系統開銷。 */
三種內存分配算法具體實現:
1 //首次適應算法,空閑區大小按起始地址升序排序 2 /* 3 從空前分區表的第一個表目查找該表,把最先能夠滿足要求的空閑區分配給作業,這種方法的目的在於減少查找時間 4 */ 5 void rearrange_FF(){ 6 //使用冒泡排序方法 7 if(free_block == NULL || free_block->next == NULL) 8 return; 9 FBT *t1,*t2,*head; 10 head = free_block; 11 for(t1 = head->next;t1;t1 = t1->next){ 12 for(t2 = head;t2 != t1;t2=t2->next){ 13 /*空閑分區以地址遞增的次序鏈接,分配內存是順序查找*/ 14 if(t2->start_addr > t2->next->start_addr){ 15 int tmp = t2->start_addr; 16 t2->start_addr = t2->next->start_addr; 17 t2->next->start_addr = tmp; 18 tmp = t2->size; 19 t2->size = t2->next->size; 20 t2->next->size = tmp; 21 } 22 } 23 } 24 } 25 //最佳適應算法,空閑分區按大小從小到大排序 26 /* 27 從全部空閑區中找出能滿足作業要求的,且大小最小的空閑分區,這種方法能使隨便盡量小 28 */ 29 void rearrange_BF(){ 30 if(free_block == NULL || free_block->next == NULL) 31 return; 32 FBT *t1,*t2,*head; 33 head = free_block; 34 for(t1 = head->next;t1;t1 = t1->next){ 35 for(t2 = head;t2 != t1;t2=t2->next){ 36 /*空閑分區按容量遞增形成分區鏈*/ 37 if(t2->size > t2->next->size){ 38 int tmp = t2->start_addr; 39 t2->start_addr = t2->next->start_addr; 40 t2->next->start_addr = tmp; 41 tmp = t2->size; 42 t2->size = t2->next->size; 43 t2->next->size = tmp; 44 } 45 } 46 } 47 } 48 //最壞適應算法,空閑分區按從大到小排序 49 /* 50 它從全部空閑區中找出能滿足作業要求的、且大小最大的空閑enquirer,從而使鏈表中節點大小趨於均勻 51 */ 52 void rearrange_WF(){ 53 if(free_block == NULL || free_block->next == NULL) 54 return; 55 FBT *t1,*t2,*head; 56 head = free_block; 57 for(t1 = head->next;t1;t1 = t1->next){ 58 for(t2 = head;t2 != t1;t2=t2->next){ 59 /*空閑分區以從良遞減的次序鏈接*/ 60 if(t2->size < t2->next->size){ 61 int tmp = t2->start_addr; 62 t2->start_addr = t2->next->start_addr; 63 t2->next->start_addr = tmp; 64 tmp = t2->size; 65 t2->size = t2->next->size; 66 t2->next->size = tmp; 67 } 68 } 69 } 70 }
4. 內存釋放算法
進程終止,釋放內存,如何釋放,如何更新內存空閑分區表。給出算法源代碼,並解釋。
釋放過程:找到pid對應的鏈表節點,釋放進程該進程所占用的內存(將進程的已分配區歸還,並進行可能的合並,按地址重新品排布),釋放鏈表節點。
1 //釋放鏈表節點 2 int dispose(AB *free_ab){ 3 //釋放ab數據結構節點 4 AB *pre,*ab; 5 if(free_ab == allocated_block_head){ 6 //如果要是釋放第一個節點 7 allocated_block_head = allocated_block_head->next; 8 free(free_ab); 9 return 1; 10 } 11 pre = allocated_block_head; 12 ab = allocated_block_head->next; 13 while(ab!=free_ab){ 14 pre = ab; 15 ab = ab->next; 16 } 17 pre->next = ab->next; 18 free(ab); 19 return 2; 20 } 21 //釋放進程所占用的內存 22 int free_mem(AB *ab){ 23 //將ab所表示的已分配區歸還,並進行可能的合並 24 int algorithm = ma_algorithm; 25 FBT *fbt,*pre,*work; 26 fbt = (FBT*)malloc(sizeof(FBT)); 27 if(!fbt) return -1; 28 fbt->size = ab->size; 29 fbt->start_addr = ab->start_addr; 30 31 //插至末尾 32 work = free_block; 33 if(work == NULL){ 34 free_block = fbt; 35 fbt->next == NULL; 36 }else{ 37 while(work ->next != NULL){ 38 work = work->next; 39 } 40 fbt->next = work->next; 41 work->next = fbt; 42 } 43 //按地址重新排布 44 rearrange_FF(); 45 //合並可能分區;即若兩空閑分區相連則合並 46 pre = free_block; 47 while(pre->next){ 48 work = pre->next; 49 if(pre->start_addr + pre->size == work->start_addr ){ 50 pre->size = pre->size + work->size; 51 pre->next = work->next; 52 free(work); 53 continue; 54 }else{ 55 pre = pre->next; 56 } 57 } 58 //按照當前算法排序 59 rearrange(ma_algorithm); 60 return 1; 61 } 62 //找到pid對應的鏈表節點 63 AB *find_process(int pid){ 64 AB *tmp = allocated_block_head; 65 while(tmp != NULL){ 66 if(tmp->pid == pid){ 67 return tmp; 68 } 69 tmp = tmp->next; 70 } 71 printf("\e[0;31;1m Cannot find pid:%d \e[0m\n",pid); 72 return NULL; 73 } 74 //刪除進程 75 int kill_process(){ 76 AB *ab; 77 int pid; 78 printf("Kill Process,pid="); 79 scanf("%d",&pid); 80 ab = find_process(pid); 81 if(ab!=NULL){ 82 free_mem(ab); //釋放ab所表示的分配表 83 dispose(ab); //釋放ab數據結構節點 84 return 0; 85 }else{ 86 return -1; 87 } 88 }
進程終止模塊(kill_process):通過輸入對應pid完成對相應進程的終止功能,將其內存空間設置為空閑分區,若與已有空閑分區的地址連續,則進行空閑分區的合並。
5. 運行結果
(1)產生測試數據
寫程序,產生測試數據(隨機)。給出你的源碼,以及你生成的測試數據是什么。
1 int main(int argc, char const *argv[]){ 2 char choice; 3 pid = 0; 4 free_block = init_free_block(mem_size); //初始化空閑區 5 while(1){ 6 fflush(stdin); 7 display_menu(); //顯示菜單 8 fflush(stdin); 9 while((choice = getchar()) != '\n'){ 10 //choice = getchar(); 11 fflush(stdin); 12 switch(choice){ 13 case '1':set_mem_size();break;//設置內存大小 14 case '2':set_algorithm();flag = 1;break;//設置分配算法 15 case '3':new_process();flag = 1;break;//創建新進程 16 case '4':kill_process();flag = 1;break;//刪除進程 17 case '5':display_mem_usage();flag = 1;break;//顯示內存使用 18 case '0':do_exit();exit(0);//釋放鏈表退出 19 default: break; 20 } 21 fflush(stdin); 22 } 23 } 24 } 25 void display_menu(){ 26 puts(""); 27 printf("1 - Set memory size(fedault=%d)\n",DEFAULT_MEM_SIZE); 28 printf("2 - Select memory allocation algorithm\n"); 29 printf("3 - New process\n"); 30 printf("4 - Terminate a process \n"); 31 printf("5 - Display memory usage\n"); 32 printf("0 - Exit\n"); 33 }
測試數據:
運行結果:
(2)解釋結果
1、設置內存塊大小為1024。
2、選擇內存分配算法,FF。
3、創建新進程1,PROCESS-01,大小為10。
4、創建新進程2,PROCESS-01,大小為25。
5、設置內存分配算法,BF。
6、創建新進程3,PROCESS-03,大小為50。
7、創建新進程4,PROCESS-04,大小為80。
8、結束一個進程,pid=2。
9、設置內存分配算法,MF。
10、創建新進程5,PROCESS-05,大小為100。
附錄(所有源碼):

1 #include<stdio.h> 2 #include<stdlib.h> 3 #include "mem.h" 4 5 typedef struct free_block_type{ 6 int size; 7 int start_addr; 8 struct free_block_type *next; 9 }FBT; 10 11 typedef struct allocated_block{ 12 int pid; 13 int size; 14 int start_addr; 15 char process_name[PROCESS_NAME_LEN]; 16 struct allocated_block *next; 17 }AB; 18 19 FBT *free_block; 20 AB *allocated_block_head = NULL; 21 22 int mem_size = DEFAULT_MEM_SIZE; 23 int ma_algorithm = MA_FF; 24 static int pid = 0; 25 int flag = 0; 26 int min_mem_size = 10; 27 28 FBT *init_free_block(int mem_size); 29 void display_menu(); 30 int set_mem_size(); 31 int display_mem_usage(); 32 int dispose(AB *free_ab); 33 int free_mem(); 34 int kill_process(); 35 int allocate_mem(AB *ab); 36 int new_process(); 37 void rearrange_FF(); 38 void rearrange_BF(); 39 void rearrange_WF(); 40 void rearrange(int algorithm); 41 void set_algorithm(); 42 void do_exit(){ 43 return; 44 } 45 int main(int argc, char const *argv[]){ 46 char choice; 47 pid = 0; 48 free_block = init_free_block(mem_size); 49 while(1){ 50 fflush(stdin); 51 display_menu(); 52 fflush(stdin); 53 while((choice = getchar()) != '\n'){ 54 55 fflush(stdin); 56 switch(choice){ 57 case '1':set_mem_size();break; 58 case '2':set_algorithm();flag = 1;break; 59 case '3':new_process();flag = 1;break; 60 case '4':kill_process();flag = 1;break; 61 case '5':display_mem_usage();flag = 1;break; 62 case '0':do_exit();exit(0); 63 default: break; 64 } 65 fflush(stdin); 66 } 67 } 68 } 69 void display_menu(){ 70 puts(""); 71 printf("1 - Set memory size(fedault=%d)\n",DEFAULT_MEM_SIZE); 72 printf("2 - Select memory allocation algorithm\n"); 73 printf("3 - New process\n"); 74 printf("4 - Terminate a process \n"); 75 printf("5 - Display memory usage\n"); 76 printf("0 - Exit\n"); 77 } 78 FBT *init_free_block(int mem_size){ 79 FBT *fb; 80 fb = (FBT*)malloc(sizeof(FBT)); 81 if(fb==NULL){ 82 printf("No mem\n"); 83 return NULL; 84 } 85 fb->size = mem_size; 86 fb->start_addr = DEFAULT_MEM_START; 87 fb->next = NULL; 88 return fb; 89 } 90 int set_mem_size(){ 91 int size; 92 if(flag!=0){ 93 printf("Cannot set memory size again\n"); 94 return 0; 95 } 96 printf("Total memory size ="); 97 scanf("%d",&size); 98 if(size>0){ 99 mem_size = size; 100 free_block->size = mem_size; 101 } 102 flag = 1; 103 min_mem_size = mem_size / 100; 104 return 1; 105 } 106 int display_mem_usage(){ 107 FBT *fbt = free_block; 108 AB *ab = allocated_block_head; 109 printf("\e[0;31;1m------------------------------------------------------------------\e[0m\n"); 110 printf("\e[0;32;1mFree Memory:\e[0m\n"); 111 printf("\e[0;33;1m%20s %20s\e[0m\n"," start_addr"," size"); 112 while(fbt!=NULL){ 113 printf("%20d %20d\n",fbt->start_addr,fbt->size); 114 fbt = fbt->next; 115 } 116 printf("\n"); 117 printf("\e[0;35;1mUsed Memory:\e[0m\n"); 118 printf("\e[0;33;1m%10s %20s %20s %10s\e[0m\n","PID","ProcessName","start_addr","size"); 119 while(ab != NULL){ 120 printf("%10d %20s %20d %10d\n",ab->pid,ab->process_name,ab->start_addr,ab->size); 121 ab = ab->next; 122 } 123 printf("\e[0;31;1m------------------------------------------------------------------\e[0m\n"); 124 return 0; 125 } 126 int dispose(AB *free_ab){ 127 AB *pre,*ab; 128 if(free_ab == allocated_block_head){ 129 allocated_block_head = allocated_block_head->next; 130 free(free_ab); 131 return 1; 132 } 133 pre = allocated_block_head; 134 ab = allocated_block_head->next; 135 while(ab!=free_ab){ 136 pre = ab; 137 ab = ab->next; 138 } 139 pre->next = ab->next; 140 free(ab); 141 return 2; 142 } 143 int free_mem(AB *ab){ 144 int algorithm = ma_algorithm; 145 FBT *fbt,*pre,*work; 146 fbt = (FBT*)malloc(sizeof(FBT)); 147 if(!fbt) return -1; 148 fbt->size = ab->size; 149 fbt->start_addr = ab->start_addr; 150 151 work = free_block; 152 if(work == NULL){ 153 free_block = fbt; 154 fbt->next == NULL; 155 }else{ 156 while(work ->next != NULL){ 157 work = work->next; 158 } 159 fbt->next = work->next; 160 work->next = fbt; 161 } 162 rearrange_FF(); 163 pre = free_block; 164 while(pre->next){ 165 work = pre->next; 166 if(pre->start_addr + pre->size == work->start_addr ){ 167 pre->size = pre->size + work->size; 168 pre->next = work->next; 169 free(work); 170 continue; 171 }else{ 172 pre = pre->next; 173 } 174 } 175 rearrange(ma_algorithm); 176 return 1; 177 } 178 AB *find_process(int pid){ 179 AB *tmp = allocated_block_head; 180 while(tmp != NULL){ 181 if(tmp->pid == pid){ 182 return tmp; 183 } 184 tmp = tmp->next; 185 } 186 printf("\e[0;31;1m Cannot find pid:%d \e[0m\n",pid); 187 return NULL; 188 } 189 int kill_process(){ 190 AB *ab; 191 int pid; 192 printf("Kill Process,pid="); 193 scanf("%d",&pid); 194 ab = find_process(pid); 195 if(ab!=NULL){ 196 free_mem(ab); 197 dispose(ab); 198 return 0; 199 }else{ 200 return -1; 201 } 202 } 203 int find_free_mem(int request){ 204 FBT *tmp = free_block; 205 int mem_sum = 0; 206 while(tmp){ 207 if(tmp->size >= request){ 208 return 1; 209 } 210 mem_sum += tmp->size; 211 tmp = tmp->next; 212 } 213 if(mem_sum >= request){ 214 return 0; 215 } 216 else{ 217 return -1; 218 } 219 220 } 221 void sort_AB(){ 222 if(allocated_block_head == NULL || allocated_block_head->next == NULL) 223 return; 224 AB *t1,*t2,*head; 225 head = allocated_block_head; 226 for(t1 = head->next;t1;t1 = t1->next){ 227 for(t2 = head;t2 != t1;t2=t2->next){ 228 if(t2->start_addr > t2->next->start_addr){ 229 int tmp = t2->start_addr; 230 t2->start_addr = t2->next->start_addr; 231 t2->next->start_addr = tmp; 232 233 tmp = t2->size; 234 t2->size = t2->next->size; 235 t2->next->size = tmp; 236 } 237 } 238 } 239 } 240 void reset_AB(int start){ 241 AB *tmp = allocated_block_head; 242 while(tmp != NULL){ 243 tmp->start_addr = start; 244 start += tmp->size; 245 tmp = tmp->next; 246 } 247 } 248 void memory_compact(){ 249 FBT *fbttmp = free_block; 250 AB *abtmp = allocated_block_head; 251 252 int sum = 0; 253 while(fbttmp!=NULL){ 254 sum += fbttmp->size; 255 fbttmp = fbttmp->next; 256 } 257 fbttmp = free_block; 258 fbttmp->size = sum; 259 fbttmp->start_addr = 0; 260 fbttmp->next=NULL; 261 262 263 FBT *pr = free_block->next; 264 while(pr != NULL){ 265 fbttmp = pr->next; 266 free(pr); 267 pr = fbttmp; 268 } 269 sort_AB(); 270 reset_AB(sum); 271 272 } 273 void do_allocate_mem(AB *ab){ 274 int request = ab->size; 275 FBT *tmp = free_block; 276 while(tmp != NULL){ 277 if(tmp->size >= request){ 278 279 ab->start_addr = tmp->start_addr; 280 int shengyu = tmp->size - request; 281 if(shengyu <= min_mem_size){ 282 ab->size = tmp->size; 283 if(tmp == free_block){ 284 free_block = free_block->next; 285 free(tmp); 286 }else{ 287 FBT *t = free_block; 288 while(t->next != tmp){ 289 t = t->next; 290 } 291 t->next = tmp->next; 292 free(tmp); 293 } 294 } 295 else{ 296 tmp->size = shengyu; 297 tmp->start_addr = tmp->start_addr + request; 298 } 299 return ; 300 } 301 tmp = tmp->next; 302 } 303 } 304 int allocate_mem(AB *ab){ 305 FBT *fbt,*pre; 306 int request_size=ab->size; 307 fbt = pre = free_block; 308 int f = find_free_mem(request_size); 309 if(f == -1){ 310 //不夠分配 311 printf("Free mem is not enough,Allocate fail!\n"); 312 return -1; 313 }else{ 314 if(f == 0){ 315 memory_compact(); 316 } 317 do_allocate_mem(ab); 318 } 319 rearrange(ma_algorithm); 320 return 1; 321 } 322 int new_process(){ 323 AB *ab; 324 int size; 325 int ret; 326 ab = (AB*)malloc(sizeof(AB)); 327 if(!ab) exit(-5); 328 329 ab->next=NULL; 330 pid++; 331 sprintf(ab->process_name,"PROCESS-%02d",pid); 332 ab->pid = pid; 333 printf("Memory for %s:",ab->process_name); 334 scanf("%d",&size); 335 if(size>0) ab->size=size; 336 ret = allocate_mem(ab); 337 if((ret == 1) && (allocated_block_head == NULL)){ 338 allocated_block_head = ab; 339 return 1; 340 }else if(ret == 1){ 341 ab->next = allocated_block_head; 342 allocated_block_head = ab; 343 return 2; 344 }else if(ret == -1){ 345 printf("\e[0;31;1m Allocation fail \e[0m\n"); 346 free(ab); 347 return -1; 348 } 349 return 3; 350 } 351 void rearrange_FF(){ 352 if(free_block == NULL || free_block->next == NULL) 353 return; 354 FBT *t1,*t2,*head; 355 head = free_block; 356 for(t1 = head->next;t1;t1 = t1->next){ 357 for(t2 = head;t2 != t1;t2=t2->next){ 358 if(t2->start_addr > t2->next->start_addr){ 359 int tmp = t2->start_addr; 360 t2->start_addr = t2->next->start_addr; 361 t2->next->start_addr = tmp; 362 363 tmp = t2->size; 364 t2->size = t2->next->size; 365 t2->next->size = tmp; 366 } 367 } 368 } 369 } 370 void rearrange_BF(){ 371 if(free_block == NULL || free_block->next == NULL) 372 return; 373 FBT *t1,*t2,*head; 374 head = free_block; 375 for(t1 = head->next;t1;t1 = t1->next){ 376 for(t2 = head;t2 != t1;t2=t2->next){ 377 if(t2->size > t2->next->size){ 378 int tmp = t2->start_addr; 379 t2->start_addr = t2->next->start_addr; 380 t2->next->start_addr = tmp; 381 382 tmp = t2->size; 383 t2->size = t2->next->size; 384 t2->next->size = tmp; 385 } 386 } 387 } 388 } 389 void rearrange_WF(){ 390 if(free_block == NULL || free_block->next == NULL) 391 return; 392 FBT *t1,*t2,*head; 393 head = free_block; 394 for(t1 = head->next;t1;t1 = t1->next){ 395 for(t2 = head;t2 != t1;t2=t2->next){ 396 if(t2->size < t2->next->size){ 397 int tmp = t2->start_addr; 398 t2->start_addr = t2->next->start_addr; 399 t2->next->start_addr = tmp; 400 401 tmp = t2->size; 402 t2->size = t2->next->size; 403 t2->next->size = tmp; 404 } 405 } 406 } 407 } 408 void rearrange(int algorithm){ 409 switch(algorithm){ 410 case MA_FF:rearrange_FF();break; 411 case MA_BF:rearrange_BF();break; 412 case MA_WF:rearrange_WF();break; 413 } 414 } 415 void set_algorithm(){ 416 int algorithm; 417 printf("\t1 - First Fit\n"); 418 printf("\t2 - Best Fit\n"); 419 printf("\t3 - Worst Fit\n"); 420 scanf("%d",&algorithm); 421 if(algorithm>=1 && algorithm<=3) 422 ma_algorithm = algorithm; 423 rearrange(ma_algorithm); 424 }

1 //mem.h 2 #define PROCESS_NAME_LEN 32 3 #define MIN_SLICE 10 4 #define DEFAULT_MEM_SIZE 1024 5 #define DEFAULT_MEM_START 0 6 7 #define MA_FF 1 8 #define MA_BF 2 9 #define MA_WF 3
參考文獻:
https://blog.csdn.net/baidu_35085676/article/details/78502503