内存分配算法模拟.docx
《内存分配算法模拟.docx》由会员分享,可在线阅读,更多相关《内存分配算法模拟.docx(19页珍藏版)》请在冰豆网上搜索。
内存分配算法模拟
存储管理算法的模拟
姓名:
海日汗
学号:
**********
1、概述
分区式存储管理算法主要有:
首次适应算法,最佳适应算法,最坏适应算法。
2、实验目的
模拟实现分区存储管理算法中的首次、最佳、最坏适应算法。
3、实验要求
输入:
1)当前内存空闲分区的序列,包括起始地址、空闲分区大小。
2)进程的分区请求序列。
输出要求:
1)三种算法的空闲分区队列
2)三种算法的分配结果
4、实验代码
#include"iostream"
usingnamespacestd;
#defineFree0//空闲状态
#defineBusy1//已用状态
#defineOK1//完成
#defineERROR0//出错
#defineMAX_length500//最大内存空间为500KB
intflag;
typedefstructfreeSpace//定义一个空闲区说明表结构
{
longsize;//分区大小
longaddress;//分区地址
intstate;//状态
}ElemType;
//线性表的双向链表存储结构
typedefstructDuLNode
{
ElemTypedata;
structDuLNode*prior;//前趋指针
structDuLNode*next;//后继指针
}
DuLNode,*DuLinkList;
DuLinkListhead_Node;//头结点
DuLinkListend_Node;//尾结点
intalloc(int);//内存分配
intfree(int);//内存回收
intFirst_fit(int);//首次适应算法
intBest_fit(int);//最佳适应算法
intWorst_fit(int);//最差适应算法
voidshow();//查看分配
intInitblock();//开创空间表
intInitblock()//开创带头结点的内存空间链表
{
head_Node=(DuLinkList)malloc(sizeof(DuLNode));
end_Node=(DuLinkList)malloc(sizeof(DuLNode));
head_Node->prior=NULL;//头结点的前驱指针指向空
head_Node->next=end_Node;//头结点的后继指针指向尾结点
end_Node->prior=head_Node;//尾结点的前驱指针指向头结点
end_Node->next=NULL;//尾结点的后继指针指向空
end_Node->data.address=0;//尾结点的地址是0
end_Node->data.size=MAX_length;//分区大小是最大分区
end_Node->data.state=Free;//状态是空
returnOK;
}
voidmain()
{
intch;//算法选择标记
cout<<"****存储管理算法模拟****\n";
cout<<"请输入所使用的内存分配算法:
\n";
cout<<"
(1)首次适应算法\n
(2)最佳适应算法\n(3)最差适应算法\n";
cin>>ch;
while(ch<1||ch>3)
{
cout<<"输入错误,请重新输入所使用的内存分配算法:
\n";
cin>>ch;
}
Initblock();//开创空间表
intchoice;//操作选择标记
while
(1)
{
show();
cout<<"请输入您的操作:
";
cout<<"\n1:
分配内存\n2:
回收内存\n0:
退出\n";
cin>>choice;
if(choice==1)
alloc(ch);//分配内存
elseif(choice==2)//内存回收
{
intflag;
cout<<"请输入您要释放的分区号:
";
cin>>flag;
free(flag);
}
elseif(choice==0)
break;//退出
else//输入操作有误
{
cout<<"输入有误,请重试!
"<continue;
}
}
}
//分配主存
intalloc(intch)
{
intneed=0;
cout<<"请输入需要分配的主存大小(单位:
KB):
";
cin>>need;
if(need<0||need==0)
{
cout<<"请重新输入分配大小!
"<returnERROR;
}
if(ch==2)//选择最佳适应算法
{
if(Best_fit(need)==OK)
cout<<"分配成功!
"<else
cout<<"内存不足,分配失败!
"<returnOK;
}
if(ch==3)//选择最差适应算法
{
if(Worst_fit(need)==OK)
cout<<"分配成功!
"<else
cout<<"内存不足,分配失败!
"<returnOK;
}
else//默认首次适应算法
{
if(First_fit(need)==OK)
cout<<"分配成功!
"<else
cout<<"内存不足,分配失败!
"<returnOK;
}
}
//首次适应算法
intFirst_fit(intneed)
{
DuLinkListtemp=(DuLinkList)malloc(sizeof(DuLNode));//为申请作业开辟新空间且初始化
temp->data.size=need;
temp->data.state=Busy;
DuLNode*p=head_Node->next;
while(p)
{
if(p->data.state==Free&&p->data.size==need)//现有的空闲块正好等于需要的空间大小
{
p->data.state=Busy;
returnOK;
break;
}
if(p->data.state==Free&&p->data.size>need)//现有的空闲块能满足需求且有剩余
{
temp->prior=p->prior;//修改双向链表的头尾指针,插入新申请的作业
temp->next=p;
temp->data.address=p->data.address;
p->prior->next=temp;
p->prior=temp;
p->data.address=temp->data.address+temp->data.size;
p->data.size-=need;
returnOK;
break;
}
p=p->next;
}
returnERROR;
}
//最佳适应算法
intBest_fit(intneed)
{
intch;//记录最小剩余空间
DuLinkListtemp=(DuLinkList)malloc(sizeof(DuLNode));
temp->data.size=need;
temp->data.state=Busy;
DuLNode*p=head_Node->next;
DuLNode*q=NULL;//记录最佳插入位置
while(p)//初始化最小空间和最佳位置
{
if(p->data.state==Free&&(p->data.size>=need))
{
if(q==NULL)
{
q=p;
ch=p->data.size-need;
}
elseif(q->data.size>p->data.size)
{
q=p;
ch=p->data.size-need;
}
}
p=p->next;
}
if(q==NULL)returnERROR;//没有找到空闲块
elseif(q->data.size==need)
{
q->data.state=Busy;
returnOK;
}
else
{
temp->prior=q->prior;
temp->next=q;
temp->data.address=q->data.address;
q->prior->next=temp;
q->prior=temp;
q->data.address+=need;
q->data.size=ch;
returnOK;
}
returnOK;
}
//最差适应算法
intWorst_fit(intneed)
{
intch;//记录最大剩余空间
DuLinkListtemp=(DuLinkList)malloc(sizeof(DuLNode));
temp->data.size=need;
temp->data.state=Busy;
DuLNode*p=head_Node->next;
DuLNode*q=NULL;//记录最佳插入位置
while(p)//初始化最大空间和最佳位置
{
if(p->data.state==Free&&(p->data.size>=need))
{
if(q==NULL)
{
q=p;
ch=p->data.size-need;
}
elseif(q->data.sizedata.size)
{
q=p;
ch=p->data.size-need;
}
}
p=p->next;
}
if(q==NULL)returnERROR;//没有找到空闲块
elseif(q->data.size==need)
{
q->data.state=Busy;
returnOK;
}
else
{
temp->prior=q->prior;
temp->next=q;
temp->data.address=q->data.address;
q->prior->next=temp;
q->prior=temp;
q->data.address+=need;
q->data.size=ch;
returnOK;
}
returnOK;
}
//主存回收
intfree(intflag)
{
DuLNode*p=head_Node;
for(inti=0;i<=flag;i++)
if(p!
=NULL)
p=p->next;
else
returnERROR;
p->data.state=Free;
if(p->prior!
=head_Node&&p->prior->data.state==Free)//与前面的空闲块相连
{
p->prior->data.size+=p->data.size;
p->prior->next=p->next;
p->next->prior=p->prior;
p=p->prior;
}
if(p->next!
=end_Node&&p->next->data.state==Free)//与后面的空闲块相连
{
p->data.size+=p->next->data.size;
p->next->next->prior=p;
p->next=p->next->next;
}
if(p->next==end_Node&&p->next->data.state==Free)//与最后的空闲块相连
{
p->data.size+=p->next->data.size;
p->next=NULL;
}
returnOK;
}
//显示主存分配情况
voidshow()
{
intflag=0;
cout<<"\n主存分配情况:
\n";
cout<<"++++++++++++++++++++++++++++++++++++++++++++++\n\n";
DuLNode*p=head_Node->next;
cout<<"分区号\t起始地址\t分区大小\t状态\n\n";
while(p)
{
cout<<""<cout<<""<data.address<<"\t\t";
cout<<""<data.size<<"KB\t\t";
if(p->data.state==Free)
cout<<"空闲\n\n";
else
cout<<"已分配\n\n";
p=p->next;
}
cout<<"++++++++++++++++++++++++++++++++++++++++++++++\n\n";
}
实验结果分析:
1.首先适应算法的内存分配情况:
内存分配顺序是:
150KB,85KB,62KB,120KB,15KB,30KB(只有最后结果截图下来的!
)
下面是回收内存的情况:
回收的内存分区号的顺序是:
分区1分区3分区5;
下面是回收了135分区之后的内存的情况。
(说明的是回收分区5之后原来的分区6和现在新回收的分区5和在一起成为新的一个大的空闲内存!
)
再一次分配内存:
因为这样才可以看出首次适应算法的分配内存的顺序。
分配内存的大小是65KB75KB95KB
再一次分配65KB之后:
分配75KB之后:
分配95KB之后:
(找不到95KB的空闲内存,所以分配失败!
)
明显看的出来首次适应算法的主要思想是:
当接到内存申请时,查找分区说明表,找到第一个满足申请长度的空闲区,将其分割并分配。
2.最佳适应算法
分配65KB之后:
分配75KB之后:
分配95KB之后
我们能看出最佳适应算法的主要思想是:
当接到内存申请时,查找分区说明表,找到第一个能满足申请长度的最小空闲区,将其分割并分配!
3.最差适应算法
分配65KB之后
分配75KB之后
分配95KB之后
最差适应算法的主要思想是:
当接到内存申请时,查找分区说明表,找到能满足申请要求的最大的空闲区。
我的心得:
我通过本次实验深入了解了这三个算法!
只实现内存分配情况的话,比较简单!
本次试验中我还实现了回收内存的情况!
回收内存要考虑下面几个情况:
(1)回收分区的上邻分区是空闲的,需要将这两个相邻的空闲区合并成一个更大的空闲区,修改空闲区表。
(2)回收分区的下邻分区是空闲的,需要将这两个相邻的空闲区合并成一个更大的空闲区,修改空闲区表。
(3)回收分区的上邻分区和下邻分区是空闲的,需要将这三个相邻的空闲区合并成一个更大的空闲区,修改空闲区表。
(4)回收分区的上邻和下邻分区都不是空闲的,则直接将空闲区记录在空闲区表中!
还加深理解了双向链表的一些操作!