实验四

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

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;
}

原文地址:https://www.cnblogs.com/yaohai/p/5614158.html