zoukankan      html  css  js  c++  java
  • 实验四.主存空间的分配和回收

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

    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
    ");
    51     printf("系统从低地址部分开始使用,占用100k
    
    ");
    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
    ");
    70     printf("			No.	proname	begin	size	status
    ");
    71     for(i=1;i<=sumFree;i++)
    72         printf("			No.%d	%s	%d	%d	%c
    ",i,Free[i].pn,Free[i].begin,Free[i].size,Free[i].status);
    73     
    74     printf("已分配分区表Used
    ");
    75     printf("			No.	proname	begin	size	status
    ");
    76     for(i=1;i<=sumUsed;i++)
    77         printf("			No.%d	%s	%d	%d	%c
    ",i,Used[i].pn,Used[i].begin,Used[i].size,Used[i].status);
    78 
    79     printf("内存使用情况,按起始址增长的排:
    ");
    80     printf("			No.	proname	begin	size	status
    ");
    81     for(i=1;i<=sumaddresses;i++)
    82         printf("			No.%d	%s	%d	%d	%c
    ",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( "	%s", part[i].pn );
     37     printf( "	%d", part[i].begin );
     38     printf( "	%d", part[i].size );
     39     printf( "	%d", part[i].end );
     40     printf( "	%c", part[i].status );
     41 }
     42 
     43 
     44 void Show() //显示分区 
     45 {
     46     int    i;
     47     int    n; //用n来记录分区的个数
     48     printf( "
    ================================================================" );
     49     printf( "
    已分配分区表Used:" );
     50     printf( "
    	No.	proname	begin	size	end	status" );
     51     printf( "
    	------------------------------------------------" );
     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( "
    	No.%d", n );
     60             Output( i );
     61             n++;// 记录已分配使用的分区个数
     62         }
     63     }
     64     printf( "
    " );
     65     printf( "
    ================================================================" );
     66     printf( "
    空闲分区表Free:" );
     67     printf( "
    	No.	proname	begin	size	end	status" );
     68     printf( "
    	------------------------------------------------" );
     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( "
    	No.%d", n );
     77             Output( i );
     78             n++;  //记录空闲分区的个数
     79         }
     80     }
     81     printf( "
    " );
     82     printf( "
    " );
     83     printf( "
    ================================================================" );
     84     printf( "
    内存使用情况,按起始址增长的排:" );
     85     printf( "
    printf sorted by address:" );
     86     printf( "
    	No.	proname	begin	size	end	status" );
     87     printf( "
    	------------------------------------------------" );
     88     n = 1;
     89     for ( i = 0; i < MAX; i++ )
     90     {
     91         if ( part[i].status == '-' )
     92             break;
     93         printf( "
    	No.%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( "
    请输入作业名称:" );
    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( "
    该作业大小超出最大可分配空间,请重新输入:" );
    152         getch();
    153         return;
    154     }
    155     printf( "
    请选择分配算法:" );
    156     printf( "
    1、首次适应算法(FF)" );
    157     printf( "
    2、循环首次适应算法(NF)" );
    158     printf( "
    3、最佳适应算法(BF)" );
    159     printf( "
    4、最坏适应算法(WF)" );
    160     printf( "
    请输入选项:" );
    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( "
    分配成功!" );
    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( "
    请输入回收的分区号:" );
    245     scanf( "%d", &number );
    246     if ( number == 1 )
    247     {
    248         printf( "
    系统分区无法回收" );
    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( "
    找不到分区" );
    267         return;
    268     }
    269     Merge();//合并连续的空闲分区
    270     printf( "
    回收成功!" );
    271     getch();
    272 }
    273 
    274 
    275 void main()
    276 {
    277     int selection;
    278     Init();
    279     printf( "初始化,设内存容量%dk", MAX );
    280     printf( "
    系统从低地址部分开始使用,占用%dk", part[0].size );
    281     printf("
    ");
    282     while ( 1 )
    283     {
    284         printf( "
    " );
    285         printf( "
    1、显示分区" );
    286         printf( "
    2、分配作业" );
    287         printf( "
    3、回收分区" );
    288         printf( "
    请输入选项:" );
    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 }
  • 相关阅读:
    hitb2017 sentosa writeup
    linux下system函数的简单分析
    深入Linux内核架构-虚拟文件系统-脑图
    深入Linux内核架构-进程虚拟内存-脑图
    深入Linux内核架构-进程间通信
    BCTF 2017 babyuse
    深入Linux内核架构-内存管理-脑图
    深入Linux内核架构-进程管理和调度-脑图
    zctf-2017-pwn-sandbox
    Node.js学习(3)-用express改写留言本
  • 原文地址:https://www.cnblogs.com/B5002/p/5556313.html
Copyright © 2011-2022 走看看