- 袁祎琦
- 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