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周完成)

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

    第二步:(第14周完成)

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

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

    1)        首次适应算法

    2)        循环首次适应算法

    3)        最佳适应算法

    4)        最坏适应算法

    1. 为该作业分配内存空间,分配处理流程图如下(size的值设定为1K):
    1. 屏幕显示分配后的内存分区情况。

    第三步:(第15周完成)

    完成内存空间回收;

    1. 由用户输入作业的ID,决定所要终止的作业;
    2. 判断是否存在用户所输入的ID,如果存在则进行终止,否则提示作业不存在;
    3. 判断即将终止的作业前后是否有空闲区域,如果没有则作业所占的空间独立成为一个空闲块,在未分配区表中增加一项;

    (思考:如何判断前后是否有空闲块?)

    1. 即将终止作业所占空间前后有空闲块的情况:(X代表即将被终止的作业,黑色代表内存中的空闲块)

    程序中表示内存区块的结构体如下:

    struct partition {

        char    pn[10];

        int    begin;

        int    size;

        int    end;

        char    status;

    };

                所以,判断某个即将被终止的作业所占空间前面是否有空闲块的方法是:作业空间的起始地址A.begin是否等于某个空闲块的结束地址B.end,若相等,则前面有空闲块,则需要合并;若不相等则再判断后面是否有空闲块。

    回答:如何判断?

    1. 进行四种情况的判断,然后分别做出相应的区块回收操作。

    回答:如何处理回收?

    1. 显示回收后的内存使用情况。 

    源代码:

    #include "stdio.h"
    #define N 5
    int start;//存放首址
    /*定义一个空闲区说明表结构,并初始化变量*/
    struct freearea
    {
    int startaddress;/*空闲区始址*/
    int size;/*空闲区大小*/
    int state;/*空闲区状态:0为空表目,1为可用空闲块*/
    }freeblock[N]={{20,20,1},{80,50,1},{150,30,1},{300,30,0},{600,10,1}}; /*定义为作业分配主存空间的函数alloc(),给首次适应算法调用*/
    int alloc(int applyarea) /*applyarea为作业申请量*/
    {
    int i,tag=0; /*tag为检查是否有满足作业需要的空闲区的标志*/
    for(i=0;i<N;i++) /*检查空闲区说明表是否有满足作业要求的空闲区*/
    if(freeblock[i].state==1&&freeblock[i].size>applyarea)
    {
    freeblock[i].startaddress=freeblock[i].startaddress+applyarea;
    freeblock[i].size=freeblock[i].size-applyarea;
    tag=1; /*有满足条件的空闲区时,tag置1*/
    return freeblock[i].startaddress-applyarea;
    }
    else if(freeblock[i].state==1&&freeblock[i].size==applyarea)
    {
    freeblock[i].state=0;
    tag=1; /*有满足条件的空闲区时,tag置1*/
    return freeblock[i].startaddress; /*返回为作业分配的主存地址*/
    }
    if(tag==0)
    return -1; /*没有满足条件的空闲区,分配不成功,返回-1*/
    }
    /*定义为作业分配主存空间的函数alloc2(),给循环首次适应算法调用*/
    int alloc2(int applyarea,int s) /*applyarea为作业申请量*/
    {
    int i,tag=0; /*tag为检查是否有满足作业需要的空闲区的标志*/
    for(i=s;i<N;i++)/*检查空闲区说明表是否有满足作业要求的空闲区,从上次找到的空闲去的下一个空闲分区开始找*/
    if(freeblock[i].state==1&&freeblock[i].size>applyarea)
    {
    freeblock[i].startaddress=freeblock[i].startaddress+applyarea;
    freeblock[i].size=freeblock[i].size-applyarea;
    tag=1; /*有满足条件的空闲区时,tag置1*/
    start=freeblock[i].startaddress-applyarea;
    return i;
    }
    else if(freeblock[i].state==1&&freeblock[i].size==applyarea)
    {
    freeblock[i].state=0;
    tag=1; /*有满足条件的空闲区时,tag置1*/
    start=freeblock[i].startaddress; /*返回为作业分配的主存地址*/
    return i;
    }
    if(tag==0)
    return -1; /*没有满足条件的空闲区,分配不成功,返回-1*/
    }
    /*定义为作业分配主存空间的函数alloc3(),给最佳适应算法调用*/
    int alloc3(int applyarea) /*applyarea为作业申请量*/
    {
    int i,k,h,tag=0,j=0; /*tag为检查是否有满足作业需要的空闲区的标志*/
    int a[N];
    struct freearea min;
    struct freearea mid;
    for(i=0;i<N;i++) /*检查空闲区说明表是否有满足作业要求的空闲区*/
    {
    if(freeblock[i].state==1&&freeblock[i].size==applyarea)//大小刚好相等
    {
    freeblock[i].state=0;
    tag=1; /*有满足条件的空闲区时,tag置1*/
    return freeblock[i].startaddress; /*返回为作业分配的主存地址*/
    }
    }
    for(i=0;i<N;i++)//把所有大于所要求的空闲区放入数组,挑出最小的那个
    {
    if(freeblock[i].state==1&&freeblock[i].size>applyarea)a[j++]=i;
    }
    if(j>1)
    {
    h=a[0];
    min=freeblock[h];
    //min.startaddress=freeblock[h].startaddress;
    //min.size=freeblock[h].size;
    //min.state=freeblock[h].state;
    for(k=1;k<j;k++)
    {
    h=a[k];
    if(freeblock[h].size<min.size)
    {
    mid.size=freeblock[h].size;
    mid.state=freeblock[h].state;
    mid.startaddress=freeblock[h].startaddress;
    freeblock[h].size=min.size;
    freeblock[h].state=min.state;
    freeblock[h].startaddress=min.startaddress;
    min.size=mid.size;
    min.state=mid.state;
    min.startaddress=mid.startaddress;
    }
    }
    min.startaddress=min.startaddress+applyarea;
    min.size=min.size-applyarea;
    tag=1; /*有满足条件的空闲区时,tag置1*/
    return min.startaddress-applyarea;
    }
    else if(j==1)
    {
    h=a[0];
    min=freeblock[h];
    min.startaddress=min.startaddress+applyarea;
    min.size=min.size-applyarea;
    tag=1; /*有满足条件的空闲区时,tag置1*/
    return min.startaddress-applyarea;
    }
    if(tag==0)
    return -1; /*没有满足条件的空闲区,分配不成功,返回-1*/
    }
    /*定义主存回收函数:setfree() tag1代表释放区的高地址是否邻接一个空闲区,
    tag2代表释放区的高低地址是否都邻接一个空闲区,
    tag3代表释放区的低地址是否邻接一个空闲区*/
    void setfree()
    {
    int s,l,tag1=0,tag2=0,tag3=0,i,j;
    printf("input free area startaddress: ");
    scanf("%d",&s); /*输入释放区的开始地址*/
    printf("input free area size: ");
    scanf("%d",&l); /*输入释放区的大小*/
    for(i=0;i<N;i++)
    {
    if(freeblock[i].startaddress==s+l&&freeblock[i].state==1)
    {
    l=l+freeblock[i].size;
    tag1=1; /*有与释放区高地址邻接的空闲区,tag1置1*/
    for(j=0;j<N;j++)
    if(freeblock[j].startaddress+freeblock[j].size==s&&freeblock[j].state==1)
    {
    freeblock[i].state=0;
    freeblock[j].size=freeblock[j].size+l;
    tag2=1;/*有与释放区上下都邻接的空闲区,tag2置1*/
    break;
    }
    if(tag2==0) /*无与释放区高低地址邻接的空闲区*/
    {
    freeblock[i].startaddress=s;
    freeblock[i].size=l;
    break;
    }
    }
    }
    if(tag1==0) /*无与释放区高地址邻接的空闲区,并检查是否低地址有邻接空闲区*/
    {
    for(i=0;i<N;i++)
    if(freeblock[i].startaddress+freeblock[i].size==s&&freeblock[i].state==1)
    {
    freeblock[i].size=freeblock[i].size+l;
    tag3=1; /*有与释放区低地址邻接的空闲区*/
    break;
    }
    if(tag3==0) /*无与释放区低地址邻接的空闲区*/
    for(j=0;j<N;j++)
    if(freeblock[j].state==0)/*找一个空表目,将释放区放入表中*/
    {
    freeblock[j].startaddress=s;
    freeblock[j].size=l;
    freeblock[j].state=1;
    break;
    }
    }
    }
    /*定义对空闲区表中的空闲区调整的函数adjust(),
    使空闲区按始地址从小到大排列,
    空表目放在最后面*/
    void adjust()
    {
    int i,j;
    struct freearea middata;
    for(i=0;i<N;i++) /*将空闲区按始地址顺序在表中排列*/
    for(j=0;j<N;j++)
    if(freeblock[j].startaddress>freeblock[j+1].startaddress)
    {
    middata.startaddress=freeblock[j].startaddress;
    middata.size=freeblock[j].size;
    middata.state=freeblock[j].state;
    freeblock[j].startaddress=freeblock[j+1].startaddress;
    freeblock[j].size=freeblock[j+1].size;
    freeblock[j].state=freeblock[j+1].state;
    freeblock[j+1].startaddress=middata.startaddress;
    freeblock[j+1].size=middata.size;
    freeblock[j+1].state=middata.state;
    }
    for(i=0;i<N;i++) /*将空表目放在表后面*/
    for(j=0;j<N;j++)
    if(freeblock[j].state==0&&freeblock[j+1].state==1)
    {
    middata.startaddress=freeblock[j].startaddress;
    middata.size=freeblock[j].size;
    middata.state=freeblock[j].state;
    freeblock[j].startaddress=freeblock[j+1].startaddress;
    freeblock[j].size=freeblock[j+1].size;
    freeblock[j].state=freeblock[j+1].state;
    freeblock[j+1].startaddress=middata.startaddress;
    freeblock[j+1].size=middata.size;
    freeblock[j+1].state=middata.state;
    }
    }
    /*定义打印空闲区说明表函数:print()*/
    void print()
    {
    int i;
    printf(" | start size state | ");
    for(i=0;i<N;i++)
    {
    printf(" | %3d %3d %3d | ", freeblock[i].startaddress,freeblock[i].size,freeblock[i].state);
    }
    }
    //首次
    void firstFit()
    {
    int applyarea,start,j;
    char end;
    getchar();
    printf(" 是否有作业等待? y or n:");
    while((end=getchar())=='y')
    {
    printf("at first the free memory is this: ");
    adjust(); /*对空闲区表中的空闲区调整的函数*/
    print(); /*打印空闲区表的初始状态*/
    printf("input request memory size:");
    scanf("%d",&applyarea);/*输入作业的申请量*/
    start=alloc(applyarea);/*调用alloc()函数为作业分配空间,start为返回的始地址*/
    if(start==-1) /*alloc()分配不成功时,返回-1*/
    printf("there is no fit memory,please wait ");
    else
    {
    adjust();
    printf("after allocation,the free memory is this: ");
    print(); /*打印空闲区表*/
    printf("job's memory start address is:%d ",start);
    printf("job size is:%d ",applyarea);
    printf("job is running. ");
    printf("job is terminated. ");
    }
    for(j=1;j<100000;j++);/*延迟时间*/
    setfree(); /*主存回收函数*/
    adjust(); /*调整空闲区说明表*/
    print(); /*打印空闲区表函数*/
    printf("是否有作业等待? y/n:");
    end=getchar();/*是否有作业等待?有(Y)无(N)*/
    }
    }
    //循环首次
    void nextFit()
    {
    int applyarea,i=0,j;
    char end;
    getchar();
    printf(" 是否有作业等待? y or n:");
    while((end=getchar())=='y')
    {
    printf("at first the free memory is this: ");
    adjust(); /*对空闲区表中的空闲区调整的函数*/
    print(); /*打印空闲区表的初始状态*/
    printf("input request memory size:");
    scanf("%d",&applyarea);/*输入作业的申请量*/
    if(i==N-1)
    {
    i=alloc2(applyarea,i);
    if(i==-1)i=0;
    }
    else if(i<N-1)
    i=alloc2(applyarea,i); //start=alloc2(applyarea,start);/*调用alloc2()函数为作业分配空间,start为返回的始地址*/
    if(i==-1) /*alloc2()分配不成功时,返回-1*/
    printf("there is no fit memory,please wait ");
    else
    {
    adjust();
    printf("after allocation,the free memory is this: ");
    print(); /*打印空闲区表*/
    printf("job's memory start address is:%d ",start);
    printf("job size is:%d ",applyarea);
    printf("job is running. ");
    printf("job is terminated. ");
    }
    for(j=1;j<100000;j++);/*延迟时间*/
    setfree(); /*主存回收函数*/
    adjust(); /*调整空闲区说明表*/
    print(); /*打印空闲区表函数*/
    printf("是否有作业等待? y/n:");
    end=getchar();/*是否有作业等待?有(Y)无(N)*/
    }
    }
    //最佳适应算法
    void bestFit()
    {
    int applyarea,start,j;
    char end;
    getchar();
    printf(" 是否有作业等待? y or n:");
    while((end=getchar())=='y')
    {
    printf("at first the free memory is this: ");
    adjust(); /*对空闲区表中的空闲区调整的函数*/
    print(); /*打印空闲区表的初始状态*/
    printf("input request memory size:");
    scanf("%d",&applyarea);/*输入作业的申请量*/
    start=alloc3(applyarea);/*调用alloc()函数为作业分配空间,start为返回的始地址*/
    if(start==-1) /*alloc()分配不成功时,返回-1*/
    printf("there is no fit memory,please wait ");
    else
    {
    adjust();
    printf("after allocation,the free memory is this: ");
    print(); /*打印空闲区表*/
    printf("job's memory start address is:%d ",start);
    printf("job size is:%d ",applyarea);
    printf("job is running. ");
    printf("job is terminated. ");
    }
    for(j=1;j<100000;j++);/*延迟时间*/
    setfree(); /*主存回收函数*/
    adjust(); /*调整空闲区说明表*/
    print(); /*打印空闲区表函数*/
    printf("是否有作业等待? y/n:");
    end=getchar();/*是否有作业等待?有(Y)无(N)*/
    }
    }
    void FirstChoose()
    {
    printf(" 请选择: ");
    printf(" a:首次适应 ");
    printf(" b:循环首次 ");
    printf(" c:最佳适应 ");
    printf(" d:退出 ");
    printf(" 请选择操作方式: ");
    }
    /*主函数*/
    main()
    {
    char s;
    FirstChoose();
    s=getchar();
    while(s!='d')
    {
    switch(s)
    {
    case'a':
    firstFit();
    break;
    case'b':
    nextFit();
    break;
    case'c':
    bestFit();
    break;
    case'd':
    break;
    default:
    printf("error ");
    break;
    }
    FirstChoose();
    s=getchar();
    }
    return 0;
    }

  • 相关阅读:
    eclipse发布项目到tomcat部署目录
    变量 声明、存储和范围
    十周 工程2 员工有自己的工资 扩张
    使用Xshell生成key,避免password登录linux
    android模拟器 一个错误:X Error of failed request: BadRequest (invalid request code or no such operation)
    JNI 详细解释
    设计模式(Abstract Factory)抽象工厂
    Laravel创建Model
    【cocos2d-x】3.0使用cocos-console创建,编,部署游戏
    UF访问,一些对用友最新的旗舰级产品U9一些引进(图像)
  • 原文地址:https://www.cnblogs.com/yaohai/p/5614158.html
Copyright © 2011-2022 走看看