一、 实验目的
为了合理地分配和使用这些存储空间,当用户提出申请主存储器空间时,存储管理必须根据申请者的要求,按一定的策略分析主存空间和使用情况,找出足够 的空闲区域给申请者。当作业撤离归还主存资源时,则存储管理要收回占用的主存空间。主存的分配和回收的实现是与主存储器的管理方式有关的,通过本实验帮助 我们理解在不同的存储管理方式下应怎样实现主存空间的分配和回收。
用高级语言完成一个主存空间的分配和回收模拟程序,以加深对内存分配方式及其算法的理解。
二、实验内容和要求
2.1 模拟包括3部分:
1)实现特定的内存分配算法
2)实现内存回收模拟
3)每种内存分配策略对应的碎片数统计
2.2 固定分区存储管理
假设内存容量为120KB,并且分别划分成8,16,32,64KB大小的块各一块。
一个进程所需要的内存为0到100个KB。同时假设一个进程在运行过程中所需内存的大小不变。
模拟五个进程到达请求分配与运行完回收情况,输出主存分配表.
2.3 动态分区分配存储管理
采用连续分配方式之动态分区分配存储管理,使用首次适应算法、下次适应算法、最佳适应算法和最坏适应算法4种算法完成设计(任选两种算法)。
(1)在程序运行过程,由用户指定申请与释放。
(2)设计一个已占用分区表,以保存某时刻主存空间占用情况。
(3)设计一个空闲分区表,以保存某时刻主存空间剩余情况。
(4)用两个表的变化情况,反应各进程所需内存的申请与释放情况。
三、实验方法、步骤及结果测试
3.1 源程序名:1230.c
可执行程序名:1230.exe
3.2 原理分析及流程图
3.3 主要程序段及其解释:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 const int CANUSE = 1; 5 const int CANTUSE = 0; 6 //#define MSIZE 128; 7 const int MSIZE = 128; 8 9 10 //内存分区 11 struct MZone 12 { 13 //空闲区起始地址 14 int begin_addr; 15 //一个连续空闲区的长度 16 int length; 17 //状态 18 int state; 19 //内存中任务名 20 char task_name[32]; 21 //指向下一个空闲分区 22 struct MZone *next; 23 }; 24 25 //内存头指针 26 struct MZone *Mhead = NULL; 27 28 //showmemory函数,显示当前内存分配情况 29 void showmemory() 30 { 31 struct MZone *Mpoint = Mhead; 32 33 printf("内存的使用情况 "); 34 printf("beginaddr length state task "); 35 36 while( NULL!=Mpoint) 37 { 38 printf("%dk ",Mpoint->begin_addr); 39 printf("%dk ",Mpoint->length); 40 Mpoint->state?printf("CANUSE "):printf("CANTUSE "); 41 printf("%s ",Mpoint->task_name); 42 Mpoint = Mpoint->next; 43 } 44 45 system("pause"); 46 47 } 48 49 //memoallocate函数,用于分配内存 50 void memoallocate(void) 51 { 52 struct MZone *Mnew = (struct MZone*)malloc(sizeof(struct MZone)); 53 printf("输入要分配内存大小(kb): "); 54 scanf("%d",&Mnew->length); 55 printf("输入任务名: "); 56 scanf("%s",&Mnew->task_name); 57 Minsert(Mnew)?printf("分配内存成功 "):printf("没有符合大小的空闲分区,内存分配失败。 "); 58 system("pause"); 59 free(Mnew); 60 } 61 62 //Minsert函数,功能插入任务到空闲分区 63 int Minsert(struct MZone* Mnew) 64 { 65 66 struct MZone *Zinsert = Mhead; 67 //flag用于指示是Zinsert到了NULL,既没有内存可以分配 68 int flag = 1; 69 70 while( Zinsert->length<Mnew->length || !Zinsert->state) 71 { 72 if( NULL!=Zinsert->next ) 73 { 74 Zinsert = Zinsert->next; 75 } 76 else 77 { 78 Zinsert = Zinsert->next; 79 break; 80 } 81 82 } 83 84 if( NULL==Zinsert ) 85 { 86 return 0; 87 } 88 89 if( MSIZE == Zinsert->begin_addr+Mnew->length ) 90 { 91 Zinsert->state = CANTUSE; 92 strcpy(Zinsert->task_name , Mnew->task_name); 93 Zinsert->next = NULL; 94 return 1; 95 } 96 else 97 { 98 struct MZone *Ztail = (struct MZone *)malloc(sizeof(struct MZone)); 99 Zinsert->state = CANTUSE; 100 strcpy(Zinsert->task_name , Mnew->task_name); 101 Zinsert->length = Mnew->length; 102 Zinsert->next = Ztail; 103 104 memset( Ztail, 0, sizeof(char)*32 ); 105 Ztail->begin_addr = Zinsert->begin_addr + Mnew->length; 106 Ztail->state = CANUSE; 107 Ztail->length = MSIZE - Ztail->begin_addr; 108 Ztail->next = NULL; 109 110 return 1; 111 } 112 } 113 114 //memoreturn函数,用于回收内存 115 void memoreturn(void) 116 { 117 char tname[32]; 118 printf("输入要收回的任务名 "); 119 scanf("%s",tname); 120 Mreturn(tname); 121 system("pause"); 122 } 123 124 //Mreturn函数,功能回收内存 125 int Mreturn(char taskname[]) 126 { 127 struct MZone *front = NULL; 128 struct MZone *position = Mhead; 129 struct MZone *tail = Mhead->next; 130 131 while( 0!=strcmp(position->task_name,taskname) ) 132 { 133 front = position; 134 if( NULL!=position->next ) 135 { 136 position = position->next; 137 } 138 else 139 { 140 position = NULL; 141 break; 142 } 143 tail = position->next; 144 } 145 146 if( NULL==position ) 147 { 148 printf("内存中没有此任务!"); 149 } 150 else 151 { 152 //不能用CANTUSE 153 if( NULL!=tail&&NULL!=front ) 154 { 155 156 if( front->state&&tail->state ) 157 { 158 front->length = front->length + position->length + tail->length; 159 front->next = tail->next; 160 free(position); 161 free(tail); 162 } 163 else if( front->state&&!tail->state ) 164 { 165 front->length = front->length + position->length; 166 front->next = position->next; 167 free(position); 168 } 169 else if( !front->state&&tail->state ) 170 { 171 position->length = position->length + tail->length; 172 memset( position->task_name, 0, sizeof(char)*32 ); 173 position->next = tail->next; 174 position->state = CANUSE; 175 free(tail); 176 } 177 else if( !front->state&&!tail->state ) 178 { 179 memset( position->task_name, 0, sizeof(char)*32 ); 180 position->state = CANUSE; 181 } 182 } 183 else if( NULL!=tail&&NULL==front ) 184 { 185 if( !tail->state ) 186 { 187 memset( position->task_name, 0, sizeof(char)*32 ); 188 position->state = CANUSE; 189 } 190 else 191 { 192 position->length = position->length + tail->length; 193 position->next = NULL; 194 free(tail); 195 } 196 } 197 else if( NULL==tail&&NULL!=front ) 198 { 199 if(front->state) 200 { 201 front->length = front->length + position->length; 202 front->next = NULL; 203 free(position); 204 } 205 else 206 { 207 memset( position->task_name, 0, sizeof(char)*32 ); 208 position->state = CANUSE; 209 } 210 } 211 else if( NULL==tail&&NULL==front ) 212 { 213 memset( position->task_name, 0, sizeof(char)*32 ); 214 position->state = CANUSE; 215 } 216 printf("内存回收成功! "); 217 } 218 } 219 220 int main(void) 221 { 222 int func_ = 0; 223 224 //初始化Mhead 225 Mhead = (struct MZone*)malloc(sizeof(struct MZone)); 226 Mhead->begin_addr = 0; 227 Mhead->length = MSIZE; 228 Mhead->state = CANUSE; 229 memset(Mhead->task_name, 0, sizeof(char)*32 ); 230 Mhead->next = NULL; 231 232 while( 1 ) 233 { 234 printf("******************首次适应算法实现主存分配和回收系统(内存)*************** "); 235 printf("1:查看内存分配情况 "); 236 printf("2:申请分配内存 "); 237 printf("3:申请回收内存 "); 238 printf("4:退出程序 "); 239 printf("~~~~~~~~~~~~~~~~~"); 240 scanf("%d",&func_); 241 switch( func_ ) 242 { 243 case 1 :showmemory();break; 244 case 2 :memoallocate();break; 245 case 3 :memoreturn();break; 246 case 4 :return 1; 247 } 248 system("cls"); 249 } 250 }