实验四.主存空间的分配和回收

实验四主存空间的分配和回收

1.    目的和要求

1.1.           实验目的

用高级语言完成一个主存空间的分配和回收程序,以加深对动态分区分配方式及其算法的理解。

1.2.           实验要求

采用连续分配方式之动态分区分配存储管理,使用首次适应算法、循环首次适应算法、最佳适应算法和最坏适应算法4种算法完成设计。

(1)**设计一个作业申请队列以及作业完成后的释放顺序,实现主存的分配和回收。采用分区说明表进行。

(2)或在程序运行过程,由用户指定申请与释放。

(3)设计一个空闲区说明表,以保存某时刻主存空间占用情况。

 

把空闲区说明表的变化情况以及各作业的申请、释放情况显示。

2.    实验内容

根据指定的实验课题,完成设计、编码和调试工作,完成实验报告

3.    实验环境

可以选用Visual C++作为开发环境。也可以选用Windows下的VB,CB或其他可视化环境,利用各种控件较为方便。自主选择实验环境。

4.    参考数据结构:

#include<stdio.h>

#include<conio.h>

#include<string.h>

#define MAX 24

struct partition{

     

      char pn[10];

      int begin;

      int size;

      int end;  

      char status;  //

      };

typedef struct partition PART;

 

第一步:(第13周完成)

完成程序数据结构的创建,初始化内存分配情况,创建空闲分区表和已分配分区表

 1 #include<stdio.h>
 2 #include<conio.h>
 3 #include<string.h>
 4 #define MAX 24
 5 #define Memory 512
 6 struct partition{
 7     
 8     char pn[10];
 9     int begin;
10     int size;
11     int end;   ////
12     char status;  //
13     };
14 typedef struct partition PART;
15 
16 PART Free[MAX],Used[MAX],addresses[MAX];
17 int sumFree,sumUsed,sumaddresses;
18 
19 void addFree(int i,int j)
20 {
21     strcpy(addresses[i].pn,Free[j].pn);
22     addresses[i].begin=Free[j].begin;
23     addresses[i].size=Free[j].size;
24     addresses[i].status=Free[j].status;
25 }
26 
27 void addUsed(int i,int j)
28 {
29     strcpy(addresses[i].pn,Used[j].pn);
30     addresses[i].begin=Used[j].begin;
31     addresses[i].size=Used[j].size;
32     addresses[i].status=Used[j].status;
33 }
34 
35 void init()//初始化
36 {
37     
38     sumFree=0,sumUsed=0,sumaddresses=0;
39     
40     strcpy(Used[1].pn,"SYSTEM");
41     Used[1].begin=0;
42     Used[1].size=100;
43     Used[1].status='u';
44     sumUsed++;
45     
46     sumaddresses++;
47     addUsed(sumaddresses,sumUsed);
48     
49 
50     printf("初始化,设内存总容量为512k\n");
51     printf("系统从低地址部分开始使用,占用100k\n\n");
52 
53 
54 
55     strcpy(Free[1].pn,"----");
56     Free[1].begin=100;//OS占用100K
57     Free[1].size=Memory-Free[1].begin;
58     Free[1].status='f';
59     sumFree++;
60     
61     sumaddresses++;
62     addFree(sumaddresses,sumFree);
63 }
64 
65 
66 void PT()//打印
67 {
68     int i;
69     printf("空闲区表Free\n");
70     printf("\t\t\tNo.\tproname\tbegin\tsize\tstatus\n");
71     for(i=1;i<=sumFree;i++)
72         printf("\t\t\tNo.%d\t%s\t%d\t%d\t%c\n",i,Free[i].pn,Free[i].begin,Free[i].size,Free[i].status);
73     
74     printf("已分配分区表Used\n");
75     printf("\t\t\tNo.\tproname\tbegin\tsize\tstatus\n");
76     for(i=1;i<=sumUsed;i++)
77         printf("\t\t\tNo.%d\t%s\t%d\t%d\t%c\n",i,Used[i].pn,Used[i].begin,Used[i].size,Used[i].status);
78 
79     printf("内存使用情况,按起始址增长的排:\n");
80     printf("\t\t\tNo.\tproname\tbegin\tsize\tstatus\n");
81     for(i=1;i<=sumaddresses;i++)
82         printf("\t\t\tNo.%d\t%s\t%d\t%d\t%c\n",i,addresses[i].pn,addresses[i].begin,addresses[i].size,addresses[i].status);
83 }
84 
85 int main()
86 {
87     init();
88     PT();
89     return 0;
90 }

第二步:(第14周完成)

完成为某作业分配内存空间。

  1. 用户输入作业名称;
  2. 判断作业名称是否已经存在,如果存在则要求用户重新输入;
  3. 用户输入作业所占空间大小;
  4. 判断是否能够在剩余的空闲区域中找到一块放置该作业,如果不行则要求用户重新输入;
  5. 显示菜单,由用户选择使用哪一种分配算法:

1)        首次适应算法

2)        循环首次适应算法

3)        最佳适应算法

4)        最坏适应算法

6.为该作业分配内存空间,分配处理流程图如下(size的值设定为1K):

  1. 7
  2. 屏幕显示分配后的内存分区情况
  1 #include <stdio.h>
  2 #include <conio.h>
  3 #include <string.h>
  4 #define MAX 512  
  5 
  6 struct partition {
  7     char    pn[10];//分区名字
  8     int    begin;//起始地址
  9     int    size;//分区大小 
 10     int    end;//结束地址
 11     char    status;//分区状态
 12 };
 13 struct partition    part[MAX];
 14 int            p = 0; //标记上次扫描结束处 
 15 
 16 void Init()//初始化分区地址、大小以及状态
 17 {
 18     int i;
 19     for ( i = 0; i < MAX; i++ )
 20         part[i].status = '-';
 21     strcpy( part[0].pn, "SYSTEM" );
 22     part[0].begin    = 0;
 23     part[0].size    = 100;
 24     part[0].status    = 'u';
 25     strcpy( part[1].pn, "-----" );
 26     part[1].begin    = 100;
 27     part[1].size    = 412;
 28     part[1].status    = 'f';
 29     for ( i = 0; i < MAX; i++ )
 30         part[i].end = part[i].begin + part[i].size;
 31 }
 32 
 33 
 34 void Output( int i ) //以行的形式输出结构体的数据
 35 {
 36     printf( "\t%s", part[i].pn );
 37     printf( "\t%d", part[i].begin );
 38     printf( "\t%d", part[i].size );
 39     printf( "\t%d", part[i].end );
 40     printf( "\t%c", part[i].status );
 41 }
 42 
 43 
 44 void Show() //显示分区 
 45 {
 46     int    i;
 47     int    n; //用n来记录分区的个数
 48     printf( "\n================================================================" );
 49     printf( "\n已分配分区表Used:" );
 50     printf( "\n\tNo.\tproname\tbegin\tsize\tend\tstatus" );
 51     printf( "\n\t------------------------------------------------" );
 52     n = 1;
 53     for ( i = 0; i < MAX; i++ )
 54     {
 55         if ( part[i].status == '-' )
 56             break;
 57         if ( part[i].status == 'u' )
 58         {
 59             printf( "\n\tNo.%d", n );
 60             Output( i );
 61             n++;// 记录已分配使用的分区个数
 62         }
 63     }
 64     printf( "\n" );
 65     printf( "\n================================================================" );
 66     printf( "\n空闲分区表Free:" );
 67     printf( "\n\tNo.\tproname\tbegin\tsize\tend\tstatus" );
 68     printf( "\n\t------------------------------------------------" );
 69     n = 1;
 70     for ( i = 0; i < MAX; i++ )
 71     {
 72         if ( part[i].status == '-' )
 73             break;
 74         if ( part[i].status == 'f' )
 75         {
 76             printf( "\n\tNo.%d", n );
 77             Output( i );
 78             n++;  //记录空闲分区的个数
 79         }
 80     }
 81     printf( "\n" );
 82     printf( "\n" );
 83     printf( "\n================================================================" );
 84     printf( "\n内存使用情况,按起始址增长的排:" );
 85     printf( "\nprintf sorted by address:" );
 86     printf( "\n\tNo.\tproname\tbegin\tsize\tend\tstatus" );
 87     printf( "\n\t------------------------------------------------" );
 88     n = 1;
 89     for ( i = 0; i < MAX; i++ )
 90     {
 91         if ( part[i].status == '-' )
 92             break;
 93         printf( "\n\tNo.%d", n );
 94         Output( i );
 95         n++;//记录已分配分区以及空闲分区之和的总个数
 96     }
 97     getch();
 98 }
 99 
100 void Fit( int a, char workName[], int workSize ) //新作业把一个分区分配成两个分区:已使用分区和空闲分区 
101 {
102     int i;
103     for ( i = MAX; i > a + 1; i-- )
104     {
105         //通过逆向遍历,把在a地址后的所有分区往后退一个分区,目的在于增加一个分区
106         if ( part[i - 1].status == '-' )
107             continue;
108         part[i]=part[i-1];
109     }
110     strcpy( part[a + 1].pn, "-----" );
111     part[a + 1].begin    = part[a].begin + workSize;
112     part[a + 1].size    = part[a].size - workSize;
113     part[a + 1].end        = part[a].end;
114     part[a + 1].status    = 'f';
115     strcpy( part[a].pn, workName );
116     part[a].size    = workSize;
117     part[a].end    = part[a].begin + part[a].size;
118     part[a].status    = 'u';
119 }
120 
121 
122 void Allocation() // 分配 
123 {
124     int    i;
125     int    a;
126     int    workSize;
127     char    workName[10];
128     int    pFree;
129     printf( "\n请输入作业名称:" );
130     scanf( "%s", &workName );
131     for(i=0;i<MAX;i++)
132     {
133         if(!strcmp(part[i].pn,workName))//判断作业名称是否已经存在
134         {
135             printf("该作业名称已经存在,请重新输入:" );
136             return;
137         }
138     }
139     printf( "请输入作业大小(k):" );
140     scanf( "%d", &workSize );
141     for ( i = 0; i < MAX; i++ )//通过循环在空闲区找是否有适合区间存储作业
142     {
143         if ( part[i].status == 'f' && part[i].size >= workSize )
144         {
145             pFree = i;
146             break;
147         }
148     }
149     if ( i == MAX )
150     {
151         printf( "\n该作业大小超出最大可分配空间,请重新输入:" );
152         getch();
153         return;
154     }
155     printf( "\n请选择分配算法:" );
156     printf( "\n1、首次适应算法(FF)" );
157     printf( "\n2、循环首次适应算法(NF)" );
158     printf( "\n3、最佳适应算法(BF)" );
159     printf( "\n4、最坏适应算法(WF)" );
160     printf( "\n请输入选项:" );
161     while ( 1 )
162     {
163         scanf( "%d", &a );
164         if ( a == 1 || a == 2 || a == 3 || a == 4 )
165             break;
166         printf( "输入错误,请重新输入:" );
167     }
168     switch ( a )
169     {
170     case 1:
171         for ( i = 0; i < MAX; i++ )//首次适应算法(按地址从低到高查找)
172             if ( part[i].status == 'f' && part[i].size >= workSize )
173                 break;
174         Fit( i, workName, workSize );
175         break;
176     case 2:
177         for ( p; p <= MAX; p++ )//循环首次适应算法
178         {
179             if ( p == MAX )//如果p指向地址末尾还没找到适合区间,则循环返回首地址0,继续寻找
180                 p = 0;      
181             if ( part[p].status == 'f' && part[p].size >= workSize )
182                 break;
183         }
184         Fit( p, workName, workSize );
185         break;
186     case 3:
187         for ( i = 0; i < MAX; i++ )//最佳适应算法
188             if ( part[i].status == 'f' && part[i].size >= workSize )
189                 if ( part[pFree].size > part[i].size )
190                     pFree = i;//通过遍历所有区间,每次都找到最小空闲分区进行分配
191         Fit( pFree, workName, workSize );
192         break;
193     case 4:
194         for ( i = 0; i < MAX; i++ )//最坏适应算法
195             if ( part[i].status == 'f' && part[i].size >= workSize )
196                 if ( part[pFree].size < part[i].size )
197                     pFree = i;//通过遍历所有区间,每次都找到最大空闲区分配
198         Fit( pFree, workName, workSize );
199         break;
200     default:
201         break;
202     }
203     printf( "\n分配成功!" );
204     getch();
205 }
206 
207 
208 void Merge() //合并连续的空闲分区 
209 {
210     int i = 0;
211     while ( i != MAX - 1 )
212     {
213         for ( i = 0; i < MAX - 1; i++ )
214         {
215             if ( part[i].status == 'f' )
216                 if ( part[i + 1].status == 'f' )
217                 {
218                     part[i].size    = part[i].size + part[i + 1].size;
219                     part[i].end    = part[i].begin + part[i].size;
220                     i++;
221                     for ( i; i < MAX - 1; i++ )
222                     {
223                         if ( part[i + 1].status == '-' )
224                         {
225                             part[i].status = '-';
226                             break;
227                         }
228                        
229                         part[i]=part[i+1];
230                     }
231                     part[MAX - 1].status = '-';
232                     break;
233                 }
234         }
235     }
236 }
237 
238 
239 void Recovery() // 回收分区 
240 {
241     int    i;
242     int    number;
243     int    n=0;
244     printf( "\n请输入回收的分区号:" );
245     scanf( "%d", &number );
246     if ( number == 1 )
247     {
248         printf( "\n系统分区无法回收" );
249         return;
250     }
251     
252     for ( i = 0; i < MAX; i++ )//通过循环查找要回收的已使用分区区号
253     {
254         if ( part[i].status == 'u' )
255         {
256             n++;
257             if ( n == number )
258             {
259                 strcpy( part[i].pn, "-----" );
260                 part[i].status = 'f';
261             }
262         }
263     }
264     if ( i == MAX - 1 )
265     {
266         printf( "\n找不到分区" );
267         return;
268     }
269     Merge();//合并连续的空闲分区
270     printf( "\n回收成功!" );
271     getch();
272 }
273 
274 
275 void main()
276 {
277     int selection;
278     Init();
279     printf( "初始化,设内存容量%dk", MAX );
280     printf( "\n系统从低地址部分开始使用,占用%dk", part[0].size );
281     printf("\n");
282     while ( 1 )
283     {
284         printf( "\n" );
285         printf( "\n1、显示分区" );
286         printf( "\n2、分配作业" );
287         printf( "\n3、回收分区" );
288         printf( "\n请输入选项:" );
289         while ( 1 )
290         {
291             scanf( "%d", &selection );
292             if ( selection == 0 ||selection == 1 || selection == 2 || selection == 3 )
293                 break;
294             printf( "输入错误,请重新输入:" );
295         }
296         switch ( selection )
297         {
298         case 1:
299             Show(); //显示分区
300             break;
301         case 2:
302             Allocation(); //分配作业
303             break;
304         case 3:
305             Recovery();  //回收分区
306             break;
307         default:
308             break;
309         }
310     }
311 }

 

转载于:https://www.cnblogs.com/B5002/p/5556313.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值