张蒙用首次适应算法模拟内存的分配和回收Word格式.docx
《张蒙用首次适应算法模拟内存的分配和回收Word格式.docx》由会员分享,可在线阅读,更多相关《张蒙用首次适应算法模拟内存的分配和回收Word格式.docx(17页珍藏版)》请在冰豆网上搜索。
运行效果:
1.初始化内存区大小,并添加作业,选择1添加作业
2.当作业大小超过存储块大小时,分配失败。
3.选择3,可查看内存分配情况
4.选择2回收内存
5.选择1添加新作业
6.回收C作业,相邻的空闲内存块合并。
五、程序流程图:
六、实验源代码:
//FirstFit.cpp:
可变分区用首次适应算法来模拟内存回收
#include<
STDIO.H>
STDLIB.H>
intMAX_SEGMENT=10;
//最大碎片值
structPartition//分区表目
{
intPar_Size;
//分区大小
intPar_No;
//分区序号或者名字
intAddr;
//分区地址
intIsUse;
//分区使用情况,0表示空闲,1表示使用
Partition*pri;
//前向指针
Partition*next;
//后向指针
};
Partition*Int()//函数,返回Partition类型指针
{//初始化空闲分区表
Partition*list,*H,*H1;
list=(structPartition*)malloc(sizeof(structPartition));
list->
next=NULL;
H=list;
if(!
list)
{
printf("
\n错误,内存初始化分配失败!
程序结束"
);
exit
(1);
}
H1=(structPartition*)malloc(sizeof(structPartition));
printf("
请预先输入分区总大小(以KB为单位):
"
scanf("
%d"
&
H1->
Par_Size);
H1->
Addr=0;
Par_No=0;
IsUse=0;
pri=H;
H->
next=H1;
////list--->
H1
returnlist;
}
Partition*InitFP()
{//初始化已分配分区表
Partition*FP,*F,*H;
inti;
FP=(structPartition*)malloc(sizeof(structPartition));
FP->
H=FP;
for(i=0;
i<
10;
i++)//已分配区先暂定分配十个表目
F=(structPartition*)malloc(sizeof(structPartition));
if(!
F)
{
printf("
\n错误,内存分配失败!
exit
(1);
}
F->
Par_Size=0;
H->
next=F;
H=H->
next;
returnFP;
Partition*New_Process(Partition*list,Partition*FP)
{//为新的进程分配资源
Partition*H,*P,*H1;
intSize,Name,L;
H1=FP->
H=H->
请输入新作业的名称和大小(整数):
%d%d"
Name,&
Size);
while(H)
H)//表目已查完,无法分配
\n已无空闲分区,本次无法分配!
returnlist;
else{
if(H->
IsUse==0)//空表目
//if(H->
Par_Size>
=Size)//大小满足,空闲分区大小》要分配的大小
if(H->
=Size)//大小满足,
{
booltemp=false;
if((H->
Par_Size-Size)<
=MAX_SEGMENT){//空闲分区大小-要分配的大小<
碎片值,会产生碎片,将整块内存大小分配出去,
Size=H->
Par_Size;
//分配的大小为整块内存
temp=true;
//会产生碎片
}
//其他情况就分配大小为请求大小,不会产生碎片,
L=H->
Addr;
//保存空闲分地址
if(temp){
printf("
该次内存分配会产生碎片,将整块内存大小%d分配出去!
Size);
}else{
该次内存分配不会产生碎片"
}
break;
}
//否则,继续往下查找
if(H)
if(H->
Size)//大小满足,空闲分区大小》要分配的大小
P=(structPartition*)malloc(sizeof(structPartition));
//分配新的表目,处理一条数据,分配一次内存
P->
IsUse=1;
Addr=L;
//指向空闲分区地址
next=H;
//修改指针
H->
pri->
next=P;
pri=H->
pri;
pri=P;
Par_Size=Size;
//分配大小为要请求分配的大小
Par_No=Name;
//名称
Par_Size-=Size;
//修改空闲分区,H所指区块大小减Size
Addr+=Size;
//H所指区块地址加Size
}else
//大小相等的,把当前表项设置空表目
while(H1)
if(H1->
IsUse==0)
{
H1->
//保存已分配地址
//在已分配表中设置为已分配
break;
}
H1=H1->
}else
所申请资源已大过系统所拥有的,请重新输入!
\n"
Partition*Reclaim(Partition*list,Partition*FP)
{//结束作业,资源回收,No为作业名,回收内存
Partition*H1,*H2,*H3,*HF;
//H1为释放区,H2为后分区,H3为前分区
intNo;
//作业名
H1=list;
HF=FP;
//可有可无?
H1=H1->
HF=FP->
请输入您想结束的作业名:
%D"
No);
while(HF)//对已分配表进行操作
if(HF->
Par_No==No)
HF->
//标志为空表目
break;
//这时保存着HF所指分区的信息
HF=HF->
HF)//如果找不到该作业,则提示出错
所输入的作业名称不正确,请重新输入!
else{
while(H1)//对空闲表进行操作
printf("
内存回收成功"
H2=H1->
//后分区
H3=H1->
//前分区
if(H2&
&
H2->
IsUse==0)//后接分区为空闲
if(H2->
next==NULL)//判断后接分区是否为尾结点
Par_Size+=H2->
//把H2合并到H1
free(H2);
已回收%d大小内存"
H1->
}else//后分区不为空闲,表示已经被使用
next=H2->
H2->
next->
pri=H1;
if(H3&
H3->
IsUse==0)//前分区为空闲分区,则合并去前分区
H3->
Par_Size+=H1->
next=H1->
next!
=NULL)//若H1为尾结点
pri=H3;
free(H1);
voidPrint(Partition*list,Partition*FP)
{//输出已分配分区和空闲分区
Partition*H1,*H2;
H1=list->
H2=FP;
H2=H2->
****************已分配分区表*******************\n"
分区序号大小始址状态\n"
while(H2)
%d%d%d"
H2->
Par_No,H2->
Par_Size,H2->
Addr);
if(H2->
IsUse==1)
已分配\n"
else
空表目\n"
H2=H2->
**************************************************\n"
****************总的空闲分区表*******************\n"
while(H1)
Par_No,H1->
Par_Size,H1->
if(H1->
H1=H1->
voidMain_Print(Partition*list,Partition*FP)
{//主入口函数,进行菜单选择
intop;
while
(1)
\n主菜单\n"
1.申请新的作业,分配内存\n"
2.结束作业,回收内存\n"
3.查看内存表\n"
4.退出系统\n"
\n请选择:
scanf("
op);
switch(op)//根据输入,选择分支方向
case1:
New_Process(list,FP);
case2:
Reclaim(list,FP);
case3:
Print(list,FP);
case4:
default:
\n选择错误,请重新选择!
if(op==4)
//退出循环
voidmain()
{//主函数入口
structPartition*list,*FP;
list=Int();
FP=InitFP();
Main_Print(list,FP);
七、实验结果图示:
四、实验总结
通过此次的实验,让我对内存分配中首次适应算法更加熟悉,通过编程模拟实现操作系统的可变分区存储管理的功能,一方面加深对原理的理解,另一方面提高根据已有原理通过编程解决实际问题的能力,为进行系统软件开发和针对实际问题提出高效的软件解决方案打下基础。