内存的动态存储管理一、实验内容编写程序实现动态分区存储管理方式的主存分配与回收。具体内容包括:首先确定主存空间分配表;然后采用最先适应算法完成主存空间的分配与回收;最后编写主函数对所做工作进行测试二、实验原理模拟存储管理中内存空间的管理和分配内存空间的管理分为固定分区管理方式,可变分区管理方式,页式存储管理,段式存储管理。题目:模拟内存分配与回收三、实验步骤(或过程)在MicrosoftVisualC++6.0环境下运行1.设计一个空闲分区表,空闲分区表通过空闲分区链表来管理,在进行内存分配时,系统优先使用空闲分区低端的空间。2.设计一个内存分区表,可用链表管理,用以表示当前以内存使用情况。3.设计一个进程申请队列以及进程完成后的释放顺序,实现主存的分配和回收。4.要求每次分配和回收后把空闲分区的变化情况以及各进程的申请、释放情况以及各进程的申请、释放情况以图形方式显示、打印出来。最佳适应算法:该算法总是把满足要求、又是最小的空闲区分配给作业。检查空闲区说明表是否有满足作业要求的空闲区,也分为三种情况:大于,等于,小于。若检查到有“等于”的情况,就可以直接分配,若没有,则继续检查是否有“大于”的情况代码实现如下:#includestdio.h#includemalloc.h#includestdlib.h#definen64//定义内存的大小inta[n],count=0;//数组a用来保存内存使用状况1为已分配0为未分配,count用来记name数组中元素个数charname[n];//已分配内存的名称(字符类型)typedefstructlinknode{charpid;intstart;intlength;structlinknode*left,*right;}de_node;//进程节点结构体定义//head1表示未分配内存队列头指针,head2便是已分配进程队列头指针de_node*head1,*head2=NULL;structlinknode*creat()//创建一个进程节点{intlen,flag1=1;//用于表示进程是否可以创建charid;structlinknode*p;p=(de_node*)malloc(sizeof(de_node));//试图在系统内存中开辟空间创建一个进程if(p==NULL)//p为空,说明系统没有可用内存用于创建此模拟进程{printf(系统没有足够的内存可供使用!\n);//输出return(NULL);//返回空指针}printf(请输入进程id(字符类型)和长度:);//为进程输入id和分配的长度scanf(%c%d,&id,&len);fflush(stdin);//清除输入缓存if((id='a'&&id='z'||id='A'&&id='Z')&&(len0)){for(inti=0;icount;i++)//判断输入的进程名,如果已使用,返回空指针,并释放p指针if(name[i]==id){printf(此名称进程已存在!!);flag1=0;//标志位为0,表示下面对p指向内容不做修改free(p);returnNULL;}if(len==0){//如果输入要分配的进程长度为0,释放p,返回空指针printf(输入长度为0!\n);free(p);return(NULL);}if(flag1){//标志位1,可以对p指向内容进行修改p-pid=id;//idp-start=0;//初始开始内存位置,在以后会修改p-length=len;//长度p-left=NULL;//左指针p-right=NULL;//右指针name[count++]=id;//将id存入数组,count自加return(p);}//返回创建的进程的地址}else{printf(输入进程格式有误\n);free(p);return(NULL);}}//分配内存空间voiddistribute(de_node*p){de_node*q=head1,*temp;intflag=0;do{//do_while循法//判断当前指向的内存空间的长度是否满足p所申请的长度,大于就分配if(q-length=p-length){p-start=q-start;//把进程的内存开始地址指向内存的可用开始地址处q-start+=p-length;//可用地址起始改变q-length-=p-length;//可用内存长度修改for(inti=p-start;ip-start+p-length;i++)//将已分配的内存空间全部置1a[i]=1;flag=1;//表示内存可分配//队列不止一个进程,第一个满足条件,并且刚好分配完,修改指针指向if(q-length==0&&q-right!=q){if(q==head1)//如果第一个满足,修改头指针指向head1=q-right;q-left-right=q-right;q-right-left=q-left;free(q);//把这个已分配完的空间指针释放}}if(flag==1)//已做完处理直接跳出循环break;if(flag==0)//当前指向的内存不满足,指向下一个,继续判断是否满足q=q-right;}while(q!=head1);//搜索一遍可用内存序列if(flag==0){//没有可用的内存printf(没有满足的内存!\n);count--;//由于创建时加1,但在分配内存时失败,把1又减掉free(p);//把这个未分配到内存的进程释放}if(flag==1){//表示上面已分配好内存,并已修改内存链表,下面修改已分配内存的进程队列temp=head2;//把已分配内存的进程队列赋值给临时指针if(temp==NULL)//如果还还没有存在的任何的进程,说明当前是第一个{head2=p;//让头指针指向第一个进程p-left=p;//双向队列第一个左右指针都指向自己p-right=p;//双向队列第一个左右指针都指向自己}elseif(temp!=NULL){//已存在队列,把当前直接链到第一个,与上面的区别是指针指向head2=p;//让头指针指向p指向的进程p-left=temp-left;//p进程左边为原来第一个的左边p-right=temp;//p进程右边指向第一个temp-left-right=p;//原来第一个的左边为ptemp-left=p;//原来第一个的左边的进程为p}}}//对进程的回收voidreclaim(){charid;intflag=0;de_node*q=head2,*p=head1;if(head2==NULL)//表示当前没有进程{printf(已没有进程!\n);}else{//已分配内存队列如果不为空printf(输入要回收的进程id:);//输入要回收进程的idscanf(%c,&id);fflush(stdin);for(inti=0;icount;i++)//双重循环把要回收的进程找出来,并把记录的id去掉if(name[i]==id){//判断当前的进程是否满足要求for(intj=i;jcount;j++)name[j]=name[j+1];//向前覆盖name[j+1]=NULL;//置空count--;//减一}//判断是否总共只有一个进程且是够刚好也满足条件if(q-pid==id&&q-right==q&&head2==q){head2=NULL;//把已分配队列直接置空flag=1;//表示找到满足条件的进程}if(flag==0){//上面的都没找到do{if(q-pid==id){//如果找到if(q==head2)head2=q-right;q-left-right=q-right;//修改指针指向q-right-left=q-left;flag=1;break;}elseq=q-right;}while(q!=head2);}//如果找到或是遍历一遍结束if(flag==0)printf(没有此进程号!!!\n);//没有找到满足的进程if(flag==1){//表示找到了for(inti=q-start;iq-start+q-length;i++)//释放占有的内存a[i]=0;//接下来修改可用内存的队列,while(q-startp-start&&p-right!=head1){//从第一个开始找到回收回来的内存开始地址大的那个队列p=p-right;}if(p==head1)//表示比第一个的开始还小,那么就要修改头地址head1=q;//其他情况不用修改头地址,只需找到应该的位置,把此进程插进去q-left=p-left;//修改指针的指向q-right=p;p-left-right=q;p-left=q;if(q-start+q-length==p-start)//可以与后面合并的情况{q-length+=p-length;//修改指针的指向p-right-left=q;q-right=p-right;free(p);}if(q-left-start+q-left-length==q-start)//可以与前面合并的情况{q-left-length+=q-length;//修改指针的指向q-left-right=q-right;q-right-left=q-left;free(q);}}}}//打印输出voidprint(){de_node*q=head2,*p=head1;if(count==0)printf(没有进程占有内存。\n);else{printf(输出进程id号:\n);for(inti=0;icount;i++)printf(%c\t,name[i]);}printf(\n);printf(输出内存当前使用情况:\n);for(intj=0;jn;j++)printf(%d%d\t,j,a[j]);printf(\n);printf(内存初始名称为i,回收后可能会变,可以查看回收来自那个进程\n);do//输出可用内存序列{if(p!=NULL){printf(进程id:%c开始地址:%d长度%d\n,p-pid,p-start,p-length);p=p-right;}}while(p!=head1);printf(\n);printf(已分配进程队列:\n);do//已分配进程队列{if(q!=NULL){printf(进程id:%c开始地址:%d长度%d\n,q-pid,q-start,q-length);q=q-right;}}while(q!=head2);}//主函数voidmain(){intx;de_node*point,*p1;//创建内存的初始状态point=(structlinknode*)malloc(sizeof(structlinknode));head1=point;point-pid='i';point-start=0;point-length=n;head1-left=point;head1-right=point;print();while(1){printf(------MENU-------\n);printf(1----distribute(分配)\n);printf(2----reclaim(回收)\n);printf(3----view(浏览)\n);printf(4----exit(退出)\n);printf(请输入上面的选项(1--4):\n);scanf(%d,&x);fflush(stdin);switch(x){case1:{p1=creat();if(p1==NULL)printf(创建进程失败。\n);elsedistribute(