动态分区分配存储管理
目录
1、 课程设计任务、要求、目的…3
1.1 课程设计任务…3
1.2 课程设计目的和要求…3
2、 开发环境…3
3、 相关原理及算法…3
3.1 首次适应算法…3
3.2 循环首次适应算法…4
3.3 最佳适应算法…5
3.4 最坏适应算法…5
3.5 回收算法…6
3.6 紧凑算法…7
4、 系统结构和主要的算法设计思路…8
4.1 设计首次适应算法…8
4.2 设计循环首次适应算法…8
4.3 设计最佳适应算法…8
4.4 设计最坏适应算法…9
4.5 设计分区回收算法…9
4.6 设计紧凑算法…9
5、 程序实现——主要程序清单…9
6、 程序运行的主要界面和结果截图…34
7、 总结和感想体会…36
8、 参考文献…37
1、课程设计任务、要求、目的
1.1 课程设计任务
动态分区分配存储管理
1.2 课程设计目的和要求
建立描述内存分配状况的数据结构;
建立描述进程的数据结构;
使用两种方式产生进程:(a)自动产生, (b)手工输入;
在屏幕上显示内存的分配状况、每个进程的执行情况;
建立分区的分配与回收算法,支持紧凑算法;
时间的流逝可用下面几种方法模拟:
(a)按键盘,每按一次可认为过一个时 间单位; (b) 响应 WM_TIMER;
将一批进程的执行情况存入磁盘文件,以后可以读出并重放;
支持算法:首次适应算法、循环首次适应算法、最佳适应算法:最坏适应算法。
2、开发环境
Codeblocks
3、相关原理及算法
3.1 首次适应算法
首次适应算法在分配内存时,从链首开始查找,直至找到一个大小能满足要
求的空闲分区(该空闲区的大小大于或等于进程的大小)为止,在本次实验中所有空闲区被放在一个名为空闲分区块的数组中,因此,在分配空闲分区时,需要从数组首元素查起,通过和进程所需分区大小的比较判断是否满足条件,然后比较的结果,进行分类讨论:①当进程大小与空闲分区大小相等时,将该内存分配出去并删除该空闲分区即可,②当进程大小小于空闲分区的大小时,从该分区中划出一块内存空间,分配给请求者,余下的空闲分区仍然留在空闲链中,③若从链首至链尾都不能一个满足要求的分区,则表明系统中已没有足够大的内存分配给该进程,内存分配失败,返回。
3.2 循环首次适应算法
为避免低地部分留下许多很小的空闲分区,以及减少查找可用空闲分区
的开销,循环首次适应算法在为进程分配内存空间时,不再是每次都从链首
开始查找,而是从上次找到的空闲分区的下一个空闲分区开始查找,直至找
到一个能满足要求的空闲分区,循环首次适应算法对空闲分区进行分配的方法
与首次适应算法相同。在实际编写代码时,我们在首次适应算法的基础上增加了一个值,用于记录找到的空闲分区的位置,满足循环首次适应算法的要求。
3.3 最佳适应算法
最佳适应算法要求在每次为作业分配内存时,总是把能满足要求、又是最小
的空闲分区分配给作业,避免“大材小用”。为了加速寻找,该算法要求将所有
的空闲分区按其容量以从小到大的顺序形成一个空闲分区链,在本次实验中我采
取的方法是对存放空闲分区的数组按从小到大的顺序排序,从而便于查找。这样,
第一个找到的能满足要求的空闲分区必然是最佳的。
3.4 最坏适应算法
最坏适应分配算法选择空闲分区的策略正好与最佳适应算法相反,在扫描整
个空闲分区表时,总是挑选一个最大的空闲区,从中分割一部分存储空间给作业
使用,以至于存储器中缺乏大得到空闲分区。这样使得剩下的空闲区不至于太小,
产生碎片的可能性最小。
3.5 回收算法
当进程运行完毕释放内存时,系统根据回收区的首地址,从空闲区表中找到
对应的插入点,此时可能出现以下八种情况之一:
(1)回收区为第一个内存块,且与它相连的第二个内存块处于未分配的状态,此时应先将第一个内存块与第二个内存块合并,再进行回收,由于内存块的总数量少了一个,所以应将其余所有盘块统一向前移一位,并更新空闲分区
(2)回收区为第一个内存块,但与他相连的第二个内存块处于已分配的状态,此时,只需要将其设置为未分配的状态,并更新空闲分区,即可完成回收
(3)回收区为最后一个内存块,且与其相连的前一个内存块处于未分配状态,此时需要将两个内存块合并为一个内存块回收,内存块的数量减一,并更新空闲分区即可
(4)回收区为最后一个内存块,且与其相连的前一个内存块处于已分配状态,此时,只需将其状态修改为未分配,并更新空闲分区,即可完成回收
(5)回收区在中间,且其相邻的上下两个内存块都处于未分配的状态,此时,需要将三个内存块合并为一个内存块进行回收,会导致内存块的数量减2,因此,需要将受影响的内存块向前移两位,并对空闲分区进行回收即可
(6)回收区在中间,且与其相邻的上下两个内存块都处于已分配的状态,此时,只需要将该内存块的状态修改为未分配,并对空闲分区进行过更新即可
(7)回收区在中间,但与其相邻的上内存块未分配,下内存块已分配,此时,需要将该内存块与其上面的内存块进行合并回收,这会导致内存块的数量减一,因此,需要将其后面的所有内存块统一向前移一位,并对空闲分区进行更新即可
(8)回收区在中间,但与其相邻的下内存块未分配,上内存块已分配,此时,
需要将该内存块与其下面的内存块进行合并回收,这会导致内存块的数量减一,因此,需要将其后面的所有内存块统一向前移一位,并对空闲分区进行更新即可
3.6 紧凑算法
将内存中的所有作业进行移动,使它们全都相邻接。这样可把原来分散的多
个空闲小分区拼接成一个大分区,可将一个作业装入该区。
4、系统结构和主要的算法设计思路
4.1 设计首次适应算法
每次为进程分配内存时,都从空闲分区表的首个元素开始顺序查找,如果该
空闲分区与进程的大小恰好匹配,则把该空闲分区全部分配给该进程,此时已分
配出去的空闲分区被全部利用,因此可以删除该空闲分区;如果空闲分区比进程
大很多,则按需分配,分配出去的空闲分区会有部分未被使用的部分,修改这部
分空闲区的起始位置和大小;依次查找数组中各个空闲分区的大小,为进程分配
内存。分配时,从数组第一个元素开始比较,若符合条件则将该元素减去对应作
业的值。
4.2 设计循环首次适应算法
与首次适应算法类似,区别点在于每次为进程分配内存时,不再从空闲表的
首部查找起,而是改为由上一次找到的空闲分区开始查找。分配时,增加一个值
用于记录找到的空闲分区的位置。
4.3 设计最佳适应算法
每次为进程分配内存时,要求把既能满足要求,又是最小的空闲分区分配给作
业。设计算法时,要求将空闲表按从小到大排序,每次查找空闲分区表时,将满
足进程需要的第一个匹配分区分配给作业,保证了最佳适应算法的要求。
4.4 设计最坏适应算法
与最佳适应算法类似,区别点在于每次查找空闲链表时,要求将输入的作业
放置到主存中与它所需大小差距最大的空闲区中。设计算法时,要求将空闲表按
从大到小排序,每次查找空闲链表时,将满足进程需要的第一个匹配分区分配给
作业,保证了最坏适应算法的要求。
4.5 设计分区回收算法
设计一个函数,当想要回收内存时,对内存分区状态进行查找。若回收区与
插入点的前一个空闲分区 F1 相邻接,此时应将回收区与插入点的前一分区合并,不必为回收分区分配新表项,而只需修改其前一分区 F1 的大小;若回收分区与插入点的后一空闲分区 F2 相邻接,此时也可将两分区合并,形成新的空闲分区,但用回收区的首址作为新空闲区的首址,大小为两者之和;若回收区同时与插入点的前,后两个分区邻接,此时将三个分区合并,使用 F1 的表项和 F1 的首址,取消 F2 的表项,大小为三者之和;若回收区既不与 F1 相邻接,又不与 F2 邻接。这时应为回收区单独建立一新表项,填写回收区的首址和大小,并根据其首址插入到空闲链中的适当位置。
4.6 设计紧凑算法
遍历内存分区,如果分区状态已分配,则将其放如内存区的最前面。如果是
找到的第一个则起始地址为 0,否则计算起始地址,其等于已找到的已分配分区
大小之和加首元素地址。更新最后的空闲区,其大小等于所有碎片之和,起始地
址等于所有已分配分区大小之和加首地址。
5、程序实现——主要程序清单
#include
#include
#include
#include
#include
using namespace std;
ofstream stream;//输出流对象
int ary1[20][4],ary2[20][3],ary3[10];//内存分配状态,空闲分区状态,进程分配状态
int recycle,id1,m,n,q,r;
void vision(){//打印输出函数
int i,j;
if(id11)stream.open(“first_fit.txt”, ios::app);
if(id12)stream.open(“nextfirst_fit.txt”, ios::app);
if(id13)stream.open(“best_fit.txt”,ios::app);
if(id14)stream.open(“worst_fit.txt”, ios::app);
if(id15)stream.open(“compact.txt”,ios::app);
if(id16)stream.open(“huishou.txt”,ios::app);
cout<<"-------------内存分配状态-------------"<
cout<<“已分配”; stream<<“已分配”;}
else{
cout<<“未分配”; stream<<“未分配”;
}
cout <
cout<
cout<<”--------------------------"<
}
void create_pro(){//作业信息的自动产生
int i;
for(i=0;i { ary3[i]=rand()%100;//随机产生0-100的随机数
if(ary3[i]0){i–;}//随机数不能为0
}
ary3[0]=42; ary3[1]=86;
cout<<“产生”< cout<<“大小分别是:”;
0){ary1[i][2]=0;}
for(i=0;i cout<<"["<
void create_zuoye(){//作业的手动生成
int j,choice2,id3=rand()%10;
m=id3;//内存区数量
cout<<”—您将创建几个进程—:";
cin>>choice2;q=choice2;
cout<<“输入想创建的作业请求大小”<
cout<<“你创建了”<
void create_apply()//内存信息的自动产生
{
int i;
for (i=0;i
ary1[i][1]=rand()%100;//内存分区块的大小
if(i
else
ary1[i][2]=ary1[i-1][2]+ary1[i-1][1];//内存分区块的起始地址
ary1[i][3]=rand()%3;//内存块的分配状态
if(ary1[i][1]0){i–;}//分区块大小不能为0,若为0,则返回重新分配
}
int k=0;//空闲区数量
for (i=0;i
if(ary1[i][3]!=2)
{ary2[k][0]=ary1[i][0];
ary2[k][1]=ary1[i][1];
ary2[k][2]=ary1[i][2];
k++;
}
}
n=k;//空闲块数量
}
int create_fenqu(){//内存信息的手动生成
int k,x,y,o=0,a=0;
cout<<"输入想创建的内存分区块数 : " ;
cin>>k;
cout<<“输入”<
cin>>x;
ary1[i][1]=x;//大小
}
cout<<“输入内存块的分配状态”<
if(y
n++;
}
ary1[i][3]=y;//状态
}
ary1[0][2]=0;
ary1[1][2]=ary1[0][1];
for(int i=2;i
}
m=k;
for (int i=0;i
if(ary1[i][3]!=2){
ary2[a][0]=ary1[i][0];
ary2[a][1]=ary1[i][1];
ary2[a][2]=ary1[i][2];
a++;
}
}
n=a;
return m,n;
}
void first_fit()//首次适应算法
{
vision();
int i,j,k,l,d,id2;
for(i=0;i //cout<<"["<
stream.open(“first_fit.txt”, ios::app);
stream<<"["<
if(ary2[j][1]ary3[i]){//当进程占用空间等于其中一个空闲区块大小时
ary1[ary2[j][0]-1][3]=2;//将内存分配状态修改为已占用
for(k=j+1;k
ary2[k-1][1]=ary2[k][1];
ary2[k-1][2]=ary2[k][2];
}
n–;//空闲分区数量减1
}else
{ l=ary2[j][0];//获取该空闲分区的序号
d=ary1[l-1][1];//获取该未分配内存块的大小
ary1[l-1][1]=ary3[i];//将该进程分配到匹配的未分配内存块中
ary1[l-1][3]=2;//修改此时被选中的内存块的状态
m++;//内存分区块数量加1
for(k=m;k>ary2[j][0]+1;k–){//将该内存拆分为已分配和未分配两部分,已分配的部分不变,
//未分配的内存块以及后面的所有内存块向后移一位,序号也同时都加1
ary1[k-1][0]=ary1[k-2][0]+1;
ary1[k-1][1]=ary1[k-2][1];
ary1[k-1][2]=ary1[k-2][2];
ary1[k-1][3]=ary1[k-2][3];
}
//改变第k+1块内容:对应的数组是ary1[k]
l=ary2[j][0];//获取该空闲分区的序号
ary1[l][0]=l+1; ary1[l][1]=d-ary3[i];//修改剩余的未分配内存分区块的大小
ary1[l][2]=ary1[l-1][1]+ary1[l-1][2]; //修改该未分配内存分区块的起始位置
ary1[l][3]=0; //将未分配区的分配状态调整为未分配
k=0;
for(id2=0;id2
ary2[k][0]=ary1[id2][0];
ary2[k][1]=ary1[id2][1];
ary2[k][2]=ary1[id2][2];
k++;
}
}n=k;
}break;
}else//未找到可以存放该进程的内存块
{//cout<<"["<
stream<<"["<
}
}
vision();
}
}
//首次循环适应算法
void next_fit()
{
vision();
int i,j,k,s,d,id2;
for(i=0;i for(j=r;j
//cout<<"["<
stream<<"["<
if(ary3[i]ary2[j][1]){//当进程占用空间等于其中一个空闲区块大小时
k=ary2[j][0];//得到对应空闲块对应内存块的序号
k–;ary1[k][3]=2;//把对应内存块标志位上改成已分配
n–;//空闲分区数量减1
for(k=j;k
ary2[k][1]=ary2[k+1][1];
ary2[k][2]=ary2[k+1][2];
}
vision();
break;
}else{//对应的空闲块大于进程需要大小,改变内存分配情况
r=(r+1)%n; k=ary2[j][0];//获取该空闲分区的序号
d=ary1[k-1][1];//获取该未分配内存块的大小
ary1[k-1][1]=ary3[i];ary1[k-1][3]=2;//将该进程分配到匹配的未分配内存块中,
m++;//内存块数增加1
for(s=m-1;s>k;s–){//将该内存拆分为已分配和未分配两部分,已分配的部分不变,
//未分配的内存块以及后面的所有内存块向后移一位,序号也同时都加1
ary1[s][0]=ary1[s-1][0]+1;
ary1[s][1]=ary1[s-1][1];
ary1[s][2]=ary1[s-1][2];
ary1[s][3]=ary1[s-1][3];
}
//改变第k+1块内容:对应的数组是ary1[k]
ary1[k][0]=ary1[k-1][0]+1; //获取该空闲分区的序号
ary1[k][1]=d-ary1[k-1][1];//修改剩余的未分配内存分区块的大小
ary1[k][2]=ary1[k-1][1]+ary1[k-1][2];//修改该未分配内存分区块的起始位置
k=0;
for(id2=0;id2
ary2[k][0]=ary1[id2][0];
ary2[k][1]=ary1[id2][1];
ary2[k][2]=ary1[id2][2];
k++;
}
}
n=k;
vision();
break;
}
}else{
// cout<<"["<
stream<<"["<
}
}
}
}
//思路:先把空闲列表检索一遍,选出最佳答案,进行分配
void best_fit()//最佳算法:按顺序检索,把与进程要求内存大小最接近的快分配给进程
{
int i,s,e,k,l,d,id2;
int j=-9999;//用来保存最接近的答案
vision();
for(i=0;i {
e=9999;j=-9999;
for(s=0;s
e=ary2[s][1];
j=s;
}
}if(j<0){//如果没有找到满足分配要求的分区
//cout<<"["<
stream<<"["<
}else{//如果找到了则输出
//cout<<"["<
stream<<"["<
if(ary2[j][1]ary3[i]){//找到最佳分区后
k=ary2[j][0];
ary1[k-1][3]=2;
for(l=k;l
ary2[l-1][1]=ary2[l][1];
ary2[l-1][2]=ary2[l][2];
}
n–;//空闲分区数-1
}else{
//把对应的内存分配进行更改
k=ary2[j][0];//获得空闲分区序号
d=ary1[k-1][1];//找到的分区大小
ary1[k-1][1]=ary3[i];//将分区大小改为进程要求内存大小
ary1[k-1][3]=2;//状态更改为已分配
m++;//已经选择的空闲分区中没有被分配的部分导致内存区数+1
for(l=m;l>ary2[j][0]+1;l–){//改变内存分配状态,整体后移
ary1[l-1][0]=ary1[l-2][0]+1;
ary1[l-1][1]=ary1[l-2][1];
ary1[l-1][2]=ary1[l-2][2];
ary1[l-1][3]=ary1[l-2][3];
}
k=ary2[j][0];
ary1[k][0]=k+1;
ary1[k][1]=d-ary1[k-1][1];//改变分区的大小、起始地址
ary1[k][2]=ary1[k-1][1]+ary1[k-1][2];
ary1[k][3]=0;
k=0;
for(id2=0;id2
ary2[k][0]=ary1[id2][0];//更新空闲分区表
ary2[k][1]=ary1[id2][1];
ary2[k][2]=ary1[id2][2];
k++;
}
}
n=k;
for(k=j+1;k
}
}
}
vision();
}
}
//最坏适应算法
void worst_fit()
{
int i,s,k,l,d,id2;
int j=-9999;//用来保存最接近的答案
int e=-9999;//用来存放进行比较时的中间结果
vision();
for(i=0;i j=-9999;e=-9999;
for(s=0;s
e=ary2[s][1];//找到满足条件的最大的空闲区
j=s;//空闲分区序号
}
}
if(j<0){//没找到
//cout<<"["<
stream<<"["<
}else{
//cout<<"["<
stream<<"["<
if(ary2[j][1]ary3[i]){//如果进程要求的分区大小等于最大的空闲分区
k=ary2[j][0];//取该空闲分区的序号
ary1[k-1][3]=2;//状态变为已分配
for(l=k;l
ary2[l-1][1]=ary2[l][1];
ary2[l-1][2]=ary2[l][2];
}
n–;//空闲分区数-1
}else{
//把对应的内存分配进行更改
k=ary2[j][0];//取该空闲分区序号
d=ary1[k-1][1];//找到对应
ary1[k-1][1]=ary3[i];//对已分配的分区进行内存大小修改,为进程要求的分区大小
ary1[k-1][3]=2;//状态更改为已分配
m++;//选择的空闲分区中有部分大小没有进行分配,内存区数+1
for(l=m;l>ary2[j][0]+1;l–){//改变内存分配状态,整体后移
ary1[l-1][0]=ary1[l-2][0]+1;
ary1[l-1][1]=ary1[l-2][1];
ary1[l-1][2]=ary1[l-2][2];
ary1[l-1][3]=ary1[l-2][3];
}
k=ary2[j][0];//取序号
ary1[k][0]=k+1;//改变分区的大小和起始地址
ary1[k][1]=d-ary1[k-1][1];
ary1[k][2]=ary1[k-1][1]+ary1[k-1][2];
ary1[k][3]=0;//剩余的分区状态为未分配
k=0;
for(id2=0;id2
ary2[k][0]=ary1[id2][0];
ary2[k][1]=ary1[id2][1];
ary2[k][2]=ary1[id2][2];
k++;
}
}
n=k;
for(k=j+1;k
}
}
}
vision();
}
}
//回收内存算法
/共计八种情况
(1)回收区上邻接着空闲盘块,下连接着已分配盘块 (2)回收区下邻接着空闲盘块,上邻接着已分配盘块
(3)回收区上下连接的都是空闲盘块 (4)空闲区上下邻接的都是已分配盘块
(5)要回收的盘块就是第一个盘块,并且向下邻接着空闲盘块 (6)要回收的盘块就是第一个盘块,但是向下邻接着已分配盘块
(7)要回收的盘块就是最后一个盘块,并且向上邻接的是空闲盘块 (8)要回收的盘块就是最后一个盘块,但是向上邻接的是已分配盘块/
void apply_recycle()
{
int i,j,k;
if(m
ary1[0][3]=0;//回收该内存,即将该内存修改为未分配的状态
n++;//空闲区数量加1
ary2[0][0]=1; ary2[0][1]=ary1[0][1]; ary2[0][2]=ary1[0][2];//设置空闲区的序号,大小和起始地址
vision();
}else{//当内存区的数目大于一时
if(recycle
if(ary1[1][3]!=2){//当第二个盘块即ary[1]未分配时
cout<<“要回收的盘块就是第一个盘块,并且向下邻接着空闲盘块”<
stream<<“要回收的盘块就是第一个盘块,并且向下邻接着空闲盘块”<
ary1[0][1]=ary1[0][1]+ary1[1][1];//将两个内存分配区合并成一个区域更大的分配区
ary1[0][3]=0;//将该内存分配区的分配状态修改为未分配
for(i=1;i
ary1[i][1]=ary1[i+1][1];
ary1[i][2]=ary1[i+1][2];
ary1[i][3]=ary1[i+1][3];
}
m–;//内存区数量减1
k=0;
vision();
for(j=0;j
ary2[k][0]=ary1[j][0];
ary2[k][1]=ary1[j][1];
ary2[k][2]=ary1[j][2];
k++;
}
}
n=k;
vision();
}else{//当要回收的盘块是第一个盘块,但是第二个盘块是已分配的盘块时
cout<<“要回收的盘块就是第一个盘块,但是向下邻接着已分配盘块”<
stream<<“要回收的盘块就是第一个盘块,但是向下邻接着已分配盘块”<
ary1[0][3]=0;//回收第一个盘块,即将该盘块的分配状态修改为未分配
k=0;
for(j=0;j
ary2[k][0]=ary1[j][0];
ary2[k][1]=ary1[j][1];
ary2[k][2]=ary1[j][2];
k++;
}
}
n=k;
vision();
}
}
else if(recycle
if(ary1[recycle-2][3]!=2){//若要回收的盘块是最后一个盘块,并且向上邻接的是空闲盘块时
cout<<“要回收的盘块就是最后一个盘块,并且向上邻接的是空闲盘块”<
stream<<“要回收的盘块就是最后一个盘块,并且向上邻接的是空闲盘块”<
ary1[recycle-2][3]=0;//将与该盘块相邻的盘块设置为未分配的状态
ary1[recycle-2][1]=ary1[recycle-2][1]+ary1[recycle-1][1];//将两个盘块合并为一个盘块
m–;//内存分区数目减1
k=0;
for(j=0;j
if(ary1[j][3]!=2)
{ ary2[k][0]=ary1[j][0];
ary2[k][1]=ary1[j][1];
ary2[k][2]=ary1[j][2];
k++;
}
}
n=k;
vision();
}else{//要回收的盘块是最后一个盘块,但是向上邻接的是已分配盘块时
cout<<“要回收的盘块就是最后一个盘块,但是向上邻接的是已分配盘块”<
stream<<“要回收的盘块就是最后一个盘块,但是向上邻接的是已分配盘块”<
ary1[recycle-1][3]=0;//将最后一个盘块的分配状态修改为已分配的状态
k=0;
for(j=0;j
ary2[k][0]=ary1[j][0];
ary2[k][1]=ary1[j][1];
ary2[k][2]=ary1[j][2];
k++;
}
}
n=k;
vision();
}
}
else{
if((ary1[recycle-2][3]!=2)&&(ary1[recycle][3]2)){//当回收区上邻接着空闲盘块,下连接着已分配盘块时
cout<<“回收区上邻接着空闲盘块,下连接着已分配盘块”<
stream<<“回收区上邻接着空闲盘块,下连接着已分配盘块”<
ary1[recycle-2][1]=ary1[recycle-2][1]+ary1[recycle-1][1];//将要回收的盘快与上面的空闲盘块合并成一个盘快
for(i=recycle-1;i
ary1[i][1]=ary1[i+1][1];
ary1[i][2]=ary1[i+1][2];
ary1[i][3]=ary1[i+1][3];
}
m–;//内存分配区数量减1
k=0;
for(j=0;j
ary2[k][0]=ary1[j][0];
ary2[k][1]=ary1[j][1];
ary2[k][2]=ary1[j][2];
k++;
}
}
n=k;
vision();
}
if((ary1[recycle][3]!=2)&&(ary1[recycle-2][3]2)){//当回收区下邻接着空闲盘块,上邻接着已分配盘块时
cout<<“回收区下邻接着空闲盘块,上邻接着已分配盘块”<
stream<<“回收区下邻接着空闲盘块,上邻接着已分配盘块”<
ary1[recycle-2][3]=0;//将该盘块的状态修改为已分配的状态
ary1[recycle-2][1]=ary1[recycle-2][1]+ary1[recycle-1][1];//将该盘块与他后面的未分配的盘块合并为一个盘快
for(i=recycle-1;i
ary1[i][1]=ary1[i+1][1];
ary1[i][2]=ary1[i+1][2];
ary1[i][3]=ary1[i+1][3];
}
m–;//内存分配区数量减1
k=0;
for(j=0;j
ary2[k][0]=ary1[j][0];
ary2[k][1]=ary1[j][1];
ary2[k][2]=ary1[j][2];
k++;
}
}
n=k;
vision();
}
if((ary1[recycle-2][3]!=2)&&(ary1[recycle][3]!=2)){//当回收区上下连接的都是空闲盘块时
cout<<“回收区上下连接的都是空闲盘块”<
stream<<“回收区下邻接着空闲盘块,上邻接着已分配盘块”<
ary1[recycle-2][1]=ary1[recycle-2][1]+ary1[recycle-1][1]+ary1[recycle][1];//将三个盘块合并为一个盘快
cout<<“回收区上下连接的都是空闲盘块”<
ary1[recycle-1][1]=ary1[recycle+1][1];
ary1[recycle-1][2]=ary1[recycle+1][2];
ary1[recycle-1][3]=ary1[recycle+1][3];
}
m=m-2;//内存分区块数量减1
k=0;
for(j=0;j
ary2[k][0]=ary1[j][0];
ary2[k][1]=ary1[j][1];
ary2[k][2]=ary1[j][2];
k++;
}
}
n=k;
vision();
}
if((ary1[recycle-2][3]2)&&(ary1[recycle][3]2)){//当空闲区上下邻接的都是已分配盘块时
ary1[recycle-1][3]=0;//将该盘块的分配状态修改为未分配的状态
k=0;
for(j=0;j
ary2[k][0]=ary1[j][0];
ary2[k][1]=ary1[j][1];
ary2[k][2]=ary1[j][2];
k++;
}
}
n=k;
vision();
}
}
}
}
//紧凑算法
void compact(){
int id1=0,id2,num_avl,sum_avl=0,num_apl=0;//记录已经分配的内存数量,循环量,记录空闲盘块数量,总共空闲区大小
vision();//统计总共空闲区有多大
for(id2=0;id2
}
for(id2=0;id2
ary1[num_apl][0]=num_apl+1;//序号
ary1[num_apl][1]=ary1[id2][1];//填入分区大小
if(num_apl0){//如果是第一个则起始地址为0
ary1[num_apl][2]=0;
}else{//如果不是则计算起始地址
ary1[num_apl][2]=ary1[num_apl-1][1]+ary1[num_apl-1][2];
}
ary1[num_apl][3]=2;//已分配状态
num_apl++;
}
}
ary1[num_apl][0]=num_apl+1;
ary1[num_apl][1]=sum_avl;//大小等于所有碎片大小之和
ary1[num_apl][2]=ary1[num_apl-1][1]+ary1[num_apl-1][2];//计算起始地址=前面所有分区的大小之和+第一个的起始地址
ary1[num_apl][3]=0;//未分配状态
m=num_apl+1;//包括最后一个空闲区
num_avl=0;
for(id2=0;id2
ary2[num_avl][0]=ary1[id2][0];
ary2[num_avl][1]=ary1[id2][1];
ary2[num_avl][2]=ary1[id2][2];
num_avl++;
}
}
n=num_avl;
vision();
}
int main()
{
int i,j,num,choice1,choice2;
int flag=1; //标记是否再执行
while(flag
cout<<“"<
cin>>choice1;
if(choice1
num=rand()&10;
q=num;
int id3=2+rand()%8;
m=id3;//内存区数量
create_apply();
create_pro();
}
if(choice1
create_zuoye();
create_fenqu();
}
vision();
cout<<"------------------请选择处理算法----------------------"<
if(id1
if(id1
if(id1
if(id14) {worst_fit();}
if(id15) { compact();}
if(id1==6) {
cout<<“生成内存状态"<
m=5;//内存区数量
create_apply();
vision();
cout<<“请您从空闲列表中选出需要回收的内存块(必须是已分配):”<
if((recycle>m)||(recycle<1)){
cout<<“错误:内存中不存在此块!”<
int id2=-9999;
for(i=0;i
cout<<“错误:输入的为空闲盘块!”<
break;
}
}
if(id2
apply_recycle();}
}
}
cout<<"
cin>>o;
flag=o;
}
}
运行结果略