首次适应算法实验报告
首次适应算法实验报告

}
if(flag==1)
printf("进程%c结束,内存回收成功!\n",jname);
else
printf("进程%c无法结束,内存回收失败!\n",jname);
//将连续的已回收的内存区合并
while(flag<3){
for(i=0;i<number-1;i++){
if(fqlist[i].flag==0||fqlist[i].flag==2){
//需要把以后的分区块往后一个位置
flag=1;
}else{
//当未使用的分区块大小不足时
sum=sum+fqlist[i].capactity;
}
}else{//当该分区块在使用时
sum=sum+fqlist[i].capactity;
}
}
if(flag==1)
printf("已为进程%c分配内存区!\n",jname);
系别
班级
学号
姓名
时间
地点
计算机科学系
计科1201
2014/12/29
机房 c105
课程名称
计算机操作系统
实验名称
内存管理
实验过程
一.实验目的
1.了解内存管理的功能;
2.掌握进程可变内存管理的几种内存分配与回收算法;
3.掌握可变分区算法中空闲分区的合并方法;
二.实验内容
实现首次适应算法;
三.实验程序
for(int j=i+1;j<number-1;j++)
{
fqlist[j]=fqlist[j+1];
实验三 最佳适应算法 实验报告

最佳适应算法实验报告一、实验目的了解首次适应算法、最佳适应方法、最差适应算法二、实验方法修改Minix操作系统的内存分配源码,实现最佳适应算法三、实验任务修改Minix操作系统中的内存分配源码,将首次适应算法更改为最佳适应算法。
重新编译系统映像文件,观察实验结果。
四、实验要点内存分配、首次适应算法、最佳适应算法。
五、实验内容5.1 minix内存分配源码安装好minix操作系统以后,minix系统的源码位于/usr/src目录中。
其中,与内存分配的相关源码则在/usr/src/servers/pm/alloc.c中。
minix系统初始的内存分配算法为首次适应算法。
在minix系统中,空闲的内存空间信息采用链表的信息储存起来,而操作系统分配内存空间的过程则是在这个链表中寻找一个合适空间,返回内存空间的地址,再更改链表中的内存空间信息。
这就是minix系统分配内存的实质。
5.2分析首次适应算法首次适应算法,指的从空闲内存块链表的第一个结点开始查找,把最先找到的满足需求的空闲内存块分配出去。
这种算法的优点是分配所需的时间较短,但这种算法会形成低地址部分形成很多的空间碎片,高地址区保留大量长度较长的空闲内存块。
内存分配的操作在/usr/src/servers/pm/alloc.c源文件中的alloc_mem函数中完成。
在函数的初始位置,定义了两个用于遍历链表的指针变量,两个指针变量的定义如下:registerstruct hole *hp, *prev_ptr;而hole结构体的定义如下:PRIVATE struct hole {struct hole *h_next;phys_clicksh_base;phys_clicksh_len;} hole[NR_HOLES];先分析这个结构体的定义,这个结构体中,有三个变量,h_next是一个指向链表下一个结点的指针变量;h_base则是指向这个链表所表示的空闲内存空间的地址,h_len 则是这个空闲内存空间的长度;phys_clicks的定义可以在/usr/src/include/minix/type.h 中找到,phys_clicks的定义为:typedef unsigned intpyhs_clicks;phys_clicks其实就是无符号的整数类型。
可变分区首次适应算法

可变分区首次适应算法--操作系统实验报告题目:可变分区首次适应算法指导老师:班级:姓名:学号:时间:实验三可变分区首次适应算法一、实验目的模拟内存分配, 了解并掌握动态分区分配中所用的数据结构、分区分配算法。
回顾链表的创建,插入,删除等基本操作;深刻理解首次适应内存分配算法。
二、实验内容编程实现首次适应内存分配算法,并上机验证。
实验环境:Microsoft Visual Studio 2010三、算法描述该程序用一个链表来模拟内存的空间分布。
从键盘输入链表长度和第一个结点的首地址、以及其他各个结点所占空间大小。
然后进行申请空间,并判断所申请的大小是否符合要求,能不能进行分配。
本程序主要包括两大模块,一是建立链表模块,二是申请并分配空间模块。
四、程序清单及简单注释// 内存分配算法:#include<iostream>#include<stdlib.h>#include <conio.h>using namespace std;int size=0,count=0,part[1000],address[1000],flag[1000];//设定全局变量//*******************输出可视结果*****************//void Output(){int j;cout<<" 输出内存分配情况:"<<endl;cout<<endl;cout<<" | 分区号| 分区大小| 起始地址| 状态|"<<endl;for(j=1;j<=count;j++){cout<<" | "<<j<<" ";cout<<" | "<<part[j]<<" ";cout<<" | "<<address[j]<<" ";if(flag[j]==1)cout<<" | "<<"已分配";if(flag[j]==0)cout<<" | "<<"未分配";cout<<" |";cout<<endl;}}//******************创建原始环境******************//void Create()//指明内存空间并初步地为作业分配内存{int i=1,m=0,s=0,start=0;char contin='Y';cout<<"请输入待分配的内存大小:";cin>>size;cout<<endl;cout<<"开始为作业分配内存空间"<<endl;cout<<endl;cout<<"请输入第一次分区的首地址:";cin>>start;cout<<endl;cout<<"输入每个分区的大小,以‘Y’继续操作,以‘N’结束分区操作:"<<endl; cout<<endl;while(contin!='N'){count=i;cout<<"请输入第"<<i<<"个作业的大小:";cin>>part[i];address[i]=start;start=start+part[i];s=m;//m用来标记已分配内存的总的大小,s用来标记m之前的值m=m+part[i];flag[i]=1;//标识内存已分配if(m==size){cout<<endl;cout<<"已分配完所有内存空间,请结束操作!"<<endl;cout<<endl;contin='N';}if(m<size){cout<<endl;cout<<"是否继续? Y/N:";cin>>contin;cout<<endl;while(contin!='Y'&&contin!='N'){cout<<endl;cout<<"输入‘N’或‘Y’继续操作:";cin>>contin;cout<<endl;}if(contin=='Y')i++;if(contin=='N')//如果不继续分配内存,将剩余的空间定义为一个分区,但标记为未分配{part[++i]=size-m;count=i;//分区总数address[i]=start;//起始地址}}//if(m<size)if(m>size){cout<<endl;cout<<"申请空间超出未分配的空间大小,是否重新分配?Y/N:";cin>>contin;cout<<endl;if(contin=='N'){ flag[i]=0;part[i]=size-s;}else{start=start-part[i];//如果重新分配,恢复原来的起始地址m=s;flag[i]=0;}}//if(m>size)}//while}//**************************分配内存********************//void Distribute(){int tag=0,space=0,i,j,situation=0;//situation用来表示分配是否成功cout<<endl;cout<<"输入作业所需的内存空间:";cin>>space;cout<<endl;for(i=1;i<=count;i++){if(part[i]==space&&flag[i]==0){flag[i]=1;Output();situation=1;break;}if(part[i]>space&&flag[i]==0){flag[i]=1;cout<<"分配成功!"<<endl;cout<<endl;for(j=count+1;j>=i+2;j--){part[j]=part[j-1];flag[j]=flag[j-1];}flag[i+1]=0;//多余的内存部分状态为未分配part[i+1]=part[i]-space;part[i]=space;//划出一部分内存空间分配给作业flag[count+1]=0;++count;//重新定义分区的首地址for(j=1;j<count;j++){address[j+1]=address[j]+part[j];}Output();situation=1;break;}}if(situation==0){cout<<"分配失败!"<<endl;cout<<endl;for(j=1;j<=count;j++)//判断是什么原因造成分配失败{if(flag[j]==0){tag=1;break;}}if(tag==1)cout<<"所有的空间大小都不足以分配!"<<endl<<endl;if(tag==0)cout<<"所有的空间均已分配!"<<endl<<endl;;Output();}}//********************回收分配出去的内存**********************// void Restore(){int tag=0,i,j,m=0,k;for(i=1;i<=count;i++){if(flag[i]==1){tag=1;break;}}if(tag==0)//回收前进行判断内存是否已经被分配{cout<<endl;cout<<"所有分区均未分配,不需要回收操作!"<<endl; }if(tag==1){cout<<endl;cout<<"请输入要回收的分区号:";cin>>j;flag[j]=0;//回收分区//如果有几段连续的空闲分区,则将他们合并for(i=count;i>1;i--){if(flag[i]==0&&flag[i-1]==0){m++;//用以标记将被撤销的分区块数part[i-1]=part[i-1]+part[i];part[i]=0; //先将后一个分区的大小和地址置空address[i]=0;}}for(i=count;i>=1;i--){if(address[i]!=0){ k=i; break;}elsecount--;}//处理末位连续的空闲分区for(i=k;i>1;i--)//处理中间的连续的空闲分区{if(address[i]==0){for(j=i;j<k;j++){part[j]=part[j+1];address[j]=address[j+1];flag[j]=flag[j+1];}--count;//撤销一个区分,总数减一}}Output();}}//********************主函数*********************//void main(){int i;char ch='y',s;cout<<endl<<endl<<"\t\t\t可变分区首次适应算法"<<endl<<endl;cout<<endl;for(i=0;i<1000;i++){part[i]=0;address[i]=0;//初始化数组的值flag[i]=0;}Create();Output();while(ch=='y'||ch=='Y'){cout<<endl;cout<<"选择操作,回收内存(R)或继续分配(D):";cin>>s;while(s!='R'&&s!='D'){cout<<endl;cout<<"请选择正确地操作,回收内存请输入R,继续分配请输入D:";cin>>s;}if(s=='R'){ Restore(); cout<<endl;}if(s=='D'){ Distribute(); cout<<endl;}cout<<"是否继续操作!是请输入'y'或'Y',否请输入任意字符以结束程序:";cin>>ch;}cout<<endl;cout<<"本程序结束执行!"<<endl;}五、实验结果建立内存分配环境:剩余空间不足以分配:所有的空间均已分配:回收分区1:回收分区2,由于两个空闲分区连续,将合并区分1和分区2:六、实验小结本算法从链首开始查找可以满足请求申请的空间大小的第一个结点,然后按照请求的大小,从该结点空间中划分一块适当的空间分配,剩下的空间作为一个新的结点接到后面。
操作系统存储管理实验报告

操作系统存储管理实验报告一、实验目的本次实验的目的是通过编写一段程序,实现对内存的分配和回收操作,并验证算法的正确性和性能。
二、实验内容1.实现首次适应算法首次适应算法是一种动态分配的内存管理算法,通过从低地址往高地址内存块,找到第一个满足需求的空闲块进行分配。
具体实现过程如下:(1)初始化内存空间,设置内存块的大小和地址范围;(2)编写一个函数,实现内存的分配操作,根据需求大小找到第一个合适的空闲块,并在其前后设置相应的标志位;(3)编写一个函数,实现内存的回收操作,根据释放块的地址,将其前后的标志位进行合并;(4)模拟应用程序的运行,测试内存的分配和回收操作。
2.实现最佳适应算法最佳适应算法是一种动态分配的内存管理算法,通过整个内存空间,找到最小的满足需求的空闲块进行分配。
具体实现过程如下:(1)初始化内存空间,设置内存块的大小和地址范围;(2)编写一个函数,实现内存的分配操作,遍历整个内存空间,找到满足需求且大小最小的空闲块进行分配;(3)编写一个函数,实现内存的回收操作,根据释放块的地址,将其前后的标志位进行合并;(4)模拟应用程序的运行,测试内存的分配和回收操作。
三、实验结果1.首次适应算法经过测试,首次适应算法能够正确地进行内存的分配和回收操作,并且算法的性能良好。
尽管首次适应算法在分配过程中可能会产生碎片,但是由于它从低地址开始,可以在较短的时间内找到满足需求的空闲块。
在实际应用中,首次适应算法被广泛采用。
2.最佳适应算法经过测试,最佳适应算法能够正确地进行内存的分配和回收操作,并且算法的性能较好。
最佳适应算法会整个内存空间,找到大小最小的满足需求的空闲块。
因此,在分配过程中不会产生很多的碎片,但是算法的执行时间较长。
四、实验总结通过本次实验,我们成功地实现了首次适应算法和最佳适应算法,并对算法的正确性和性能进行了验证。
两种算法在内存的分配和回收过程中都表现出良好的性能,可广泛应用于实际场景中。
首次适应算法实验报告

操作操作系统大作业题目:首次适应算法分配内存学号: **********学生姓名:***班级:计科121首次适应算法分配内存一、问题描述在内存分配中,动态分区是根据实际的进程需求,动态地为之分配空间。
而首次适应算法分配时从表头指针开始查找可利用空间表,将找到的第一个大小不小于“请求”的空闲块的一部分分配给用户。
可利用空间表本身既不按节点的初始地址有序,也不按节点的大小有序。
用户释放内存,回收时只是将空闲块插入在链表的表头即可,此算法比较节省时间。
二、运行环境 VC6.0三、算法思想。
首次适应算法要求空闲分区链以地址递增的次序链接。
在分配内存时,从链首开始查找,直到找到一个大小能满足要求的空闲分区为止;然后按照作业大小,从该分区中划出一块内存空间分配给请求者,余下的空闲区仍留在空闲链中。
若从链首到链尾都不能找到一个能满足要求的分区,则此次分配失败。
四、实验目的在计算机系统中,为了提高内存区的利用率,必须给电脑内存区进行合理的分配。
本实验通过对内存区分配方法首次适应算法的使用,来了解内存分配的模式。
五、首次适应算法分配内存算法概要(1)结构体Typedef struct freearea//定义一个空闲区说明表结构{ long size; //分区大小long address; //分区地址int state; //状态}ElemType; // 线性表的双向链表存储结构Typedef struct DuLNode{ ElemType data;structDuLNode *prior; //前趋指针structDuLNode *next; //后继指针} DuLNode,*DuLinkList;Status Initblock(intMAX_length)//开创带头结点的内存空间链表{ block_first=(DuLinkList)malloc(sizeof(DuLNode));block_last=(DuLinkList)malloc(sizeof(DuLNode));block_first->prior=NULL; //头结点的前驱指针指向空block_first->next=block_last; //头结点的后继指针指向尾结点block_last->prior=block_first; //尾结点的前驱指针指向头结点block_last->next=NULL; //尾结点的后继指针指向空block_last->data.address=0; //尾结点的地址是0block_last->data.size=MAX_length; //分区大小是最大分区block_last->data.state=Free; //状态是空return OK; }(2)主要函数说明:void alloc();进行内存分配的功能函数。
实验四操作系统存储管理实验报告

实验四操作系统存储管理实验报告一、实验目的本次实验的主要目的是深入理解操作系统中存储管理的基本原理和方法,通过实际操作和观察,掌握内存分配与回收、页面置换算法等关键概念,并能够分析和解决存储管理中可能出现的问题。
二、实验环境本次实验在装有 Windows 操作系统的计算机上进行,使用了 Visual Studio 等编程工具和相关的调试环境。
三、实验内容(一)内存分配与回收算法实现1、首次适应算法首次适应算法从内存的起始位置开始查找,找到第一个能够满足需求的空闲分区进行分配。
在实现过程中,我们通过建立一个空闲分区链表来管理内存空间,每次分配时从表头开始查找。
2、最佳适应算法最佳适应算法会选择能够满足需求且大小最小的空闲分区进行分配。
为了实现该算法,在空闲分区链表中,分区按照大小从小到大的顺序排列,这样在查找时能够快速找到最合适的分区。
3、最坏适应算法最坏适应算法则选择最大的空闲分区进行分配。
同样通过对空闲分区链表的排序和查找来实现。
(二)页面置换算法模拟1、先进先出(FIFO)页面置换算法FIFO 算法按照页面进入内存的先后顺序进行置换,即先进入内存的页面先被置换出去。
在模拟过程中,使用一个队列来记录页面的进入顺序。
2、最近最久未使用(LRU)页面置换算法LRU 算法根据页面最近被使用的时间来决定置换顺序,最近最久未使用的页面将被置换。
通过为每个页面设置一个时间戳来记录其最近使用的时间,从而实现置换策略。
3、时钟(Clock)页面置换算法Clock 算法使用一个环形链表来模拟内存中的页面,通过指针的移动和页面的访问标志来决定置换页面。
四、实验步骤(一)内存分配与回收算法的实现步骤1、初始化内存空间,创建空闲分区链表,并为每个分区设置起始地址、大小和状态等信息。
2、对于首次适应算法,从链表表头开始遍历,找到第一个大小满足需求的空闲分区,进行分配,并修改分区的状态和大小。
3、对于最佳适应算法,在遍历链表时,选择大小最接近需求的空闲分区进行分配,并对链表进行相应的调整。
操作系统 首次最佳适应算法

学号专业姓名实验日期教师签字成绩实验报告【实验名称】采用可变式分区管理,使用首次获最佳适应算法实现内存分配与回收【实验目的与原理】1、理解首次获最佳适应算法的内涵,并熟练掌握该算法。
2、学会可变式分区管理的原理是即在处理作业过程中建立分区,使分区大小正好适合作业的需要,并且分区个数是可以调整的。
3、当有一个新作业要求装入主存时,必须查空闲区说明表,从中找出一个足够大的空闲区没有时应将空闲区一分为二。
为了便于快速查找,要不断地对表格进行紧缩,即让“空表目”项留在表的后部。
4、当一个作业执行完成时,作业所占用的分区应归还给系统。
作业的释放区与空闲区的邻接分以下四种情况考虑:①释放区下邻(低地址邻接)空闲区;②释放区上邻(高地址邻接)空闲区③释放区上下都与空闲区邻接;④释放区与空闲区不邻接。
【实验内容】#include<stdio.h>#include<iostream>#include<string>using namespace std;const int MAXJOB=100;//定义表最大记录数typedef struct node{int front;int length;char data[20];}job;job frees[MAXJOB];//定义空闲区表int free_quantity;job occupys[MAXJOB];//定义已分配区表int occupy_quantity;//初始化函数void initial(){int i;for(i=0;i<MAXJOB;i++){frees[i].front=-1;frees[i].length=0;strcpy(frees[i].data,"free");occupys[i].front=-1;occupys[i].length=0;strcpy(occupys[i].data," ");}free_quantity=0;occupy_quantity=0;}//创建空闲分区表int creatfree(){FILE *fp;char fname[20];cout<<"请输入空闲区数据文件来源的文件名:"; cin>>fname;if((fp=fopen(fname,"r"))==NULL){cout<<"错误,文件打不开,请检查文件名"<<endl; }else{while(!feof(fp)){fscanf(fp,"%d\t%d\n",&frees[free_quanti ty].front,&frees[free_quantity].length);free_quantity++;}cout<<"空闲的分区表已建立!\n";return 1;}return 0;}void sort()//将free空间安首地址从小到大的顺序排列{int i,j,p;for(i=0;i<free_quantity-1;i++){p=i;for(j=i+1;j<free_quantity;j++){if(frees[j].front<frees[p].front){p=j;}}if(p!=i){frees[free_quantity]=frees[i];frees[i]=frees[p];frees[p]=frees[free_quantity];}}}//显示函数void show(){int i;cout<<endl<<"----------------------------------------------------------"<<endl;cout<<"当前空闲表:"<<endl;cout<<" 起始地址长度状态"<<endl;for(i=0;i<free_quantity;i++){cout.setf(2);cout.width(12);cout<<frees[i].front;cout.width(10);cout<<frees[i].length;cout.width(8);cout<<frees[i].data<<endl;}cout<<endl<<"----------------------------------------------------------"<<endl;cout<<"当前已分配表:"<<endl;cout<<" 起始地址长度占用作业名"<<endl;for(i=0;i<occupy_quantity;i++){cout.setf(2);cout.width(12);cout<<occupys[i].front;cout.width(10);cout<<occupys[i].length;cout.width(8);cout<<occupys[i].data<<endl;}cout<<endl<<"----------------------------------------------------------"<<endl;}//最先适应分配算法void assign(){char job_name[20];int job_length;int i,j,flag,t;cout<<"请输入新申请内存空间的作业名和空间大小:";cin>>job_name;cin>>job_length;flag=0;for(i=0;i<free_quantity;i++){if(frees[i].length>=job_length)//如果空闲空间I的长度〉作业长度{flag=1; //空闲标志位就置1 }}if(flag==0){cout<<endl<<"对不起,当前没有能满足你申请长度的空闲内存,请稍候再试!"<<endl;}else{t=0;i=0;while(t==0)//为空闲区间的时候{if(frees[i].length>=job_length){t=1;}i++;//如果空闲空间I的长度不大于作业长度,I加一,判断下一个空间}i--;occupys[occupy_quantity].front=frees[i] .front;strcpy(occupys[occupy_quantity].data,jo b_name);occupys[occupy_quantity].length=job_len gth;occupy_quantity++;if(frees[i].length>job_length)//如果空间的长度大于作业的长度,{frees[i].front+=job_length;frees[i].length-=job_length;}else{for(j=i;j<free_quantity-1;j++){frees[j]=frees[j+1];}free_quantity--;cout<<"内存空间成功:)"<<endl;}}}//撤消作业void cancel(){char job_name[20];int i,j,flag,p=0;int front;int length;cout<<"请输入要撤消的作业名:";cin>>job_name;flag=-1;for(i=0;i<occupy_quantity;i++){if(!strcmp(occupys[i].data,job_name))//当输入作业名匹配时{flag=i;front=occupys[i].front;length=occupys[i].length;}}if(flag==-1){cout<<"没有这个作业名"<<endl;}else{//加入空闲表for(i=0;i<free_quantity;i++){if((frees[i].front+frees[i].length)==fr ont)//上空{if(((i+1)<free_quantity)&&(frees[i+1].f ront==front+length))//下空{frees[i].length=frees[i].length+frees[i +1].length+length;for(j=i+1;j<free_quantity;j++){frees[j]=frees[j+1];}free_quantity--;p=1;}else{frees[i].length+=length;p=1;}}if(frees[i].front==(front+length))//下空上不空{frees[i].front=front;frees[i].length+=length;//第i 个空闲区间的长度=第i个空闲区间的长度+lengthp=1;}}if(p==0)//上下空闲区都不空{frees[free_quantity].front=front;frees[free_quantity].length=length;free_quantity++;}//删除分配表中的该作业for(i=flag;i<occupy_quantity;i++){occupys[i]=occupys[i+1];}occupy_quantity--;}}void main(){int flag=0;int t=1;int chioce=0;cout<<"*********** xxxxxxxxx***********\n"; initial();flag=creatfree();while(flag==1){sort();cout<<" 可变分区存储管理模拟系统"<<endl;cout<<" 1.申请空间 "<<endl;cout<<" 2.撤消作业 "<<endl;cout<<" 3.显示空闲表和分配表"<<endl;cout<<" 0.退出"<<endl;cout<<"请选择:";cin>>chioce;switch(chioce){case 1:assign();break;case 2:cancel();break;case 3:show();break;case 0:flag=0;break;default:cout<<"选择错误!"<<endl;}}}实验结果显示:【实验小结】本实验难度在两个方面,一是首次最佳适应算法assign(),这里我用的是结构体数组来存储空闲分区;二是对已分配分区的释放,这里同样采取结构体数组来存储已分配分区,用cancle()函数来实现。
内存回收首适应算法实验报告

操作系统实验报告——首适应算法实验报告计科101班张昊翔1007300204一.实验目的在计算机系统中,为了提高内存区的利用率,必须给电脑内存区进行合理的分配。
本实验通过对内存区域分配方法首次适应算法的使用,来了解内存的分配的模式。
二.实验要求1.内存大小初始化2.可以对内存区进行动态分配,采用首次适应算法来实现3.可以对已经分配的内存块进行回收,并合并相邻的空闲的内存块三.实验内容把一个作业装入内存,按首次适应算法对内存进行分配,作业结束,回收已经分配给该作业的内存块,并合并相邻的空闲内存块。
四.主要思想首次适应算法要求空闲分区链以地址递增的次序链接。
在分配内存时,从链首开始查找,直到找到一个大小能满足要求的空闲分区为止;然后按照作业大小,从该分区中划出一块内存空间分配给请求者,余下的空闲区仍留在空闲链中。
若从链首到链尾都不能找到一个能满足要求的分区,则此次分配失败。
五.程序流程图次适应算法的结构如图四.源代码// bank2.cpp : 定义控制台应用程序的入口点。
//#include"stdafx.h"// TODO: 在STDAFX.H 中// 引用任何所需的附加头文件,而不是在此文件中引用#include<STDIO.H>#include<STDLIB.H>int MAX_SEGMENT=10;//最大碎片值struct Partition //分区表目{ int Par_Size; //分区大小int Par_No; //分区序号或者名字int Addr; //分区地址int IsUse; //分区使用情况,0表示空闲表示使用Partition *pri; //前向指针Partition *next; //后向指针};Partition * Int()//函数返回Partition类型指针{ //初始化空闲分区表Partition *list,*H,*H1;list=(struct Partition *)malloc(sizeof(struct Partition));list->next=NULL; H=list;if(!list) { printf("\n错误,内存初始化分配失败程序结束");exit(1); }H1=(struct Partition *)malloc(sizeof(struct Partition));printf("请预先输入分区总大小(以KB为单位)");scanf_s("%d",&H1->Par_Size);H1->Addr=0; H1->Par_No=0;H1->IsUse=0; H1->pri=H; H1->next=NULL; H->next=H1;////list--->H1return list; }Partition * InitFP() { //初始化已分配分区表Partition *FP,*F,*H; int i;FP=(struct Partition *)malloc(sizeof(struct Partition));FP->next=NULL;H=FP;for(i=0;i<10;i++) //已分配区先暂定分配十个表目{F=(struct Partition *)malloc(sizeof(struct Partition));if(!F){ printf("\n错误,内存分配失败程序结束");exit(1); }F->Par_Size=0;F->Addr=0; F->Par_No=0;F->IsUse=0; F->next=NULL;H->next=F; F->pri=H; H=H->next; }return FP; }Partition * New_Process( Partition *list, Partition *FP) { //为新的进程分配资源Partition *H,*P,*H1;int Size,Name,L;H=list; H1=FP->next; H=H->next;printf("请输入新作业的名称和大小(整数):");scanf_s("%d %d",&Name,&Size);while(H){ if(!H) //表目已查完,无法分配{ printf("\n已无空闲分区,本次无法分配!");return list; }else{ if(H->IsUse==0) //空表目 //if(H->Par_Size>=Size) //大小满足,空闲分区大小》要分配的大小if(H->Par_Size>=Size) //大小满足,{ bool temp=false;if((H->Par_Size-Size)<=MAX_SEGMENT){//空闲分区大小-要分配的大小<碎片值,会产生碎片,将整块内存大小分配出去Size=H->Par_Size;//分配的大小为整块内存temp=true;//会产生碎片} //其他情况就分配大小为请求大小不会产生碎片L=H->Addr;//保存空闲分地址if(temp){printf("该次内存分配会产生碎片,将整块内存大小%d分配出去!",Size);}else{ printf("该次内存分配不会产生碎片");} break; }}H=H->next; //否则继续往下查找} if(H) {if(H->Par_Size>Size) //大小满足,空闲分区大小》要分配的大小{ P=(struct Partition *)malloc(sizeof(struct Partition)); //分配新的表目处理一条数据分配一次内存P->IsUse=1; P->Addr=L;//指向空闲分区地址P->next=H; //修改指针H->pri->next=P;P->pri=H->pri;H->pri=P;P->Par_Size=Size;//分配大小为要请求分配的大小P->Par_No=Name;//名称H->Par_Size-=Size; //修改空闲分区,H所指区块大小减SizeH->Addr+=Size;//H所指区块地址加Size}else { H->IsUse=1; //大小相等的 把当前表项设置空表目}while(H1) {if(H1->IsUse==0){ H1->Par_No=Name; H1->Par_Size=Size;H1->Addr=L;//保存已分配地址H1->IsUse=1;//在已分配表中设置为已分配break; }H1=H1->next;} }else printf("所申请资源已大过系统所拥有的,请重新输入!\n");return list; }Partition *Reclaim( Partition *list, Partition *FP){//结束作业,资源回收,No为作业名 回收内存Partition * H1,*H2,*H3,*HF;//H1为释放区 H2为后分区 H3为前分区int No; //作业名H1=list;HF=FP;//可有可无H1=H1->next;HF=FP->next;printf("请输入您想结束的作业名:");scanf_s("%D",&No);while(HF)//对已分配表进行操作{if(HF->Par_No==No){HF->IsUse=0; //标志为空表目break;//这时保存着HF所指分区的信息}HF=HF->next;} if(!HF) //如果找不到该作业 则提示出错printf("所输入的作业名称不正确,请重新输入!");else{while(H1)//对空闲表进行操作{if(H1->Par_No==No){H1->IsUse=0; //标志为空表目printf("内存回收成功");break;}H1=H1->next;}H2=H1->next;//后分区H3=H1->pri;//前分区if(H2&&H2->IsUse==0) //后接分区为空闲{if(H2->next==NULL) //判断后接分区是否为尾结点{H1->Par_Size+=H2->Par_Size; //把H2合并到H1H1->next=NULL;free(H2);printf("已回收%d大小内存",H1->Par_Size); }else//后分区不为空闲表示已经被使用{ H1->Par_Size+=H2->Par_Size;H1->next=H2->next; H2->next->pri=H1;free(H2); printf("已回收%d大小内存",H1->Par_Size);}}if(H3&&H3->IsUse==0) //前分区为空闲分区则合并去前分区{H3->Par_Size+=H1->Par_Size;H3->next=H1->next;if(H1->next!=NULL) //若H1为尾结点H1->next->pri=H3;free(H1);printf("已回收%d大小内存",H1->Par_Size);}}return list;}void Print( Partition *list, Partition *FP){ //输出已分配分区和空闲分区Partition *H1,*H2;H1=list->next;H2=FP; H2=H2->next;printf("****************已分配分区表*******************\n");printf("分区序号大小始址状态\n");while(H2){printf("%d %d %d",H2->Par_No,H2->Par_Size,H2->Addr);if(H2->IsUse==1)printf(" 已分配\n");elseprintf(" 空表目\n");H2=H2->next;}printf("**************************************************\n");printf("****************总的空闲分区表*******************\n");printf("分区序号大小始址状态\n");while(H1){printf("%d %d %d",H1->Par_No,H1->Par_Size,H1->Addr);if(H1->IsUse==1)printf(" 已分配\n");elseprintf(" 空表目\n");H1=H1->next;}printf("**************************************************\n");}void Main_Print( Partition *list, Partition *FP){ //主入口函数 进行菜单选择int op;while(1){ printf("\n 主菜单\n");printf("1.申请新的作业,分配内存\n");printf("2.结束作业,回收内存\n");printf("3.查看内存表\n");printf("4.退出系统\n");printf("\n请选择:");scanf_s("%d",&op);switch(op) //根据输入,选择分支方向{case 1: New_Process(list,FP); break;case 2: Reclaim(list,FP); break;case 3: Print(list,FP); break;case 4: break; default:printf("\n选择错误,请重新选择!");break;}if(op==4) break; //退出循环}}int main() { //主函数入口struct Partition *list,*FP;list=Int();FP=InitFP();Main_Print(list,FP); }五.输入输出。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
操作操作系统大作业题目:首次适应算法分配内存学号: **********学生姓名:***班级:计科121首次适应算法分配内存一、问题描述在内存分配中,动态分区是根据实际的进程需求,动态地为之分配空间。
而首次适应算法分配时从表头指针开始查找可利用空间表,将找到的第一个大小不小于“请求”的空闲块的一部分分配给用户。
可利用空间表本身既不按节点的初始地址有序,也不按节点的大小有序。
用户释放内存,回收时只是将空闲块插入在链表的表头即可,此算法比较节省时间。
二、运行环境 VC6.0三、算法思想。
首次适应算法要求空闲分区链以地址递增的次序链接。
在分配内存时,从链首开始查找,直到找到一个大小能满足要求的空闲分区为止;然后按照作业大小,从该分区中划出一块内存空间分配给请求者,余下的空闲区仍留在空闲链中。
若从链首到链尾都不能找到一个能满足要求的分区,则此次分配失败。
四、实验目的在计算机系统中,为了提高内存区的利用率,必须给电脑内存区进行合理的分配。
本实验通过对内存区分配方法首次适应算法的使用,来了解内存分配的模式。
五、首次适应算法分配内存算法概要(1)结构体Typedef struct freearea//定义一个空闲区说明表结构{ long size; //分区大小long address; //分区地址int state; //状态}ElemType; // 线性表的双向链表存储结构Typedef struct DuLNode{ ElemType data;structDuLNode *prior; //前趋指针structDuLNode *next; //后继指针} DuLNode,*DuLinkList;Status Initblock(intMAX_length)//开创带头结点的内存空间链表{ block_first=(DuLinkList)malloc(sizeof(DuLNode));block_last=(DuLinkList)malloc(sizeof(DuLNode));block_first->prior=NULL; //头结点的前驱指针指向空block_first->next=block_last; //头结点的后继指针指向尾结点block_last->prior=block_first; //尾结点的前驱指针指向头结点block_last->next=NULL; //尾结点的后继指针指向空block_last->data.address=0; //尾结点的地址是0block_last->data.size=MAX_length; //分区大小是最大分区block_last->data.state=Free; //状态是空return OK; }(2)主要函数说明:void alloc();进行内存分配的功能函数。
Status free(int flag)将地址为flag的分区的内存回收。
Status First_fit(int request)创建进程空间的子函数;其中,参数request表示空闲分区链的链首指针;要配合函数alloc()使用。
void show()查看内存中的分区情况。
七、代码实现#include<iostream.h>#include<stdlib.h>#include<stdio.h>#define Free 0 //空闲状态#define Busy 1 //已用状态#define OK 1 //完成#define ERROR 0 //出错//#define MAX_length 640 //最大内存空间为640KBtypedefint Status;int flag;typedefstructfreearea//定义一个空闲区说明表结构{long size; //分区大小long address; //分区地址int state; //状态}ElemType; // 线性表的双向链表存储结构typedefstructDuLNode{ElemType data;structDuLNode *prior; //前趋指针structDuLNode *next; //后继指针} DuLNode,*DuLinkList;DuLinkListblock_first; //头结点DuLinkListblock_last; //尾结点Status alloc(int);//内存分配Status free(int); //内存回收Status First_fit(int);//首次适应算法void show();//查看分配Status Initblock();//开创空间表Status Initblock(intMAX_length)//开创带头结点的内存空间链表{block_first=(DuLinkList)malloc(sizeof(DuLNode));block_last=(DuLinkList)malloc(sizeof(DuLNode));block_first->prior=NULL; //头结点的前驱指针指向空block_first->next=block_last; //头结点的后继指针指向尾结点block_last->prior=block_first; //尾结点的前驱指针指向头结点block_last->next=NULL; //尾结点的后继指针指向空block_last->data.address=0; //尾结点的地址是0block_last->data.size=MAX_length; //分区大小是最大分区block_last->data.state=Free; //状态是空return OK;}//分配主存Status alloc() {int request = 0;printf("请输入需要分配的主存大小(单位:KB):");scanf("%d",&request);if(request<0 ||request==0){printf("配大小不合适,请重试!");return ERROR;}{if(First_fit(request)==OK)printf("分配成功!");elseprintf("内存不足,分配失败!");return OK;}}//首次适应算法Status First_fit(int request){ //为申请作业开辟新空间且初始化DuLinkList temp=(DuLinkList)malloc(sizeof(DuLNode));temp->data.size=request;temp->data.state=Busy;DuLNode *p=block_first->next;while(p){if(p->data.state==Free && p->data.size==request){//有大小恰好合适的空闲块p->data.state=Busy;return OK;break;}if(p->data.state==Free && p->data.size>request){//有空闲块能满足需求且有剩余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-=request;return OK;break;}p=p->next;}return ERROR;}//主存回收Status free(int flag) {DuLNode *p=block_first;for(inti= 0; i<= flag; i++)if(p!=NULL)p=p->next;elsereturn ERROR;p->data.state=Free;if(p->prior!=block_first&& 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!=block_last&& 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==block_last&& p->next->data.state==Free)//与最后的空闲块相连{p->data.size+=p->next->data.size;p->next=NULL;}return OK;}//显示主存分配情况void show() {int flag = 0;printf("主存分配情况:\n");DuLNode *p=block_first->next;printf("分区号\t起始地址\t分区大小\t状态\n\n");while(p){printf("%d ",flag);flag++;printf("%d \t",p->data.address);printf("%dKB \t",p->data.size);if(p->data.state==Free)printf("空闲\n\n");elseprintf("已分配\n\n");p=p->next;}printf("++++++++++++++++++++++++++++++++++++++++++++++\n\n");}//主函数void main(){int c=1;intMAX_length;//算法选择标记printf("首次适应算法内存分配算法:\n");printf("input MAX_length:\n");scanf("%d",&MAX_length);Initblock(MAX_length); //开创空间表int choice;//操作选择标记while(c=1){show();printf("请输入您的操作:");printf("\n1: 分配内存\n2: 回收内存\n0: 退出\n");scanf("%d",&choice);{if(choice==1){alloc(); // 分配内存c=1;}else if(choice==2) // 内存回收{int flag;printf("请输入您要释放的分区号:\n");scanf("%d",&flag);free(flag);c=1;}else if(choice==0){break; //退出}else //输入操作有误{printf("输入有误,请重试!\n");c=1;}}printf("&&&&&&&\n");}}八、运行截图九、思考这次试验模拟内存分配,模拟了操作系统是如何通过作业调度选择作业进入内存以及系统是如何为进入内存的作业分配内存空间,实现多道作业同时驻留内存,就绪进程队列中的多个进程是如何以分式方式共享CPU,作业运行完成离开系统时,系统如何进行内存回收,采用的是首次适应算法,应用的数据结构是双向链表。