模拟了操作系统作业中内存动态分配问题。是一个简单的实现。
#include#include #include #include #include #define n 10 //假定系统允许的最大作业数量为n #define m 10 //假定系统允许的空闲区表最大为m #define minsize 1000 typedef struct workPcb{ char name[4];//name是字符串的首地址,char * a a保存着储存字符串的地址 double length; } workPcb; struct{ char name[4]; double address; //已分分区起始地址 double length; //已分分区长度,单位为字节 int flag; //已分配区表登记栏标志,“0”表示空栏目,实验中只支持一个字符的作业名 }used_table[n]; //已分配区表 //空闲区表的定义: struct { double address; //空闲区起始地址 double length; //空闲区长度,单位为字节 int flag; //空闲区表登记栏标志,用“0”表示空栏目,用“1”表示未分配 }free_table[m]; //空闲区表 //找到最小的 double freeArea=100*2*2*2*2*2*2*2*2*2*2; void distribution(workPcb* workPcb){ int k=-1,i=0; while(i<=m){ if(free_table[i].flag==1){//当第i个分区没有被分配时 if(free_table[i].length>=workPcb->length){//满足长度的分区 if(k=-1)//找出满足条件的最小的分区 k=i; else{ if(free_table[i].length length<=minsize){//当满足最小值的时候全部分配 free_table[k].flag=0; ad=free_table[k].address;//分配的起始地址 xk=free_table[k].length;//分配的长度 free_table[k].length=0; }else{ ad=free_table[k].address; free_table[k].address+=workPcb->length; xk=workPcb->length; free_table[k].length=free_table[k].length-workPcb->length; } //寻找空闲的已分配表 int j=0; while(j<=9){ if(used_table[j].flag==0){//如果有空闲的已分配表那么就分配 strcpy(used_table[j].name, workPcb->name); used_table[j].address=ad; used_table[j].length=xk; used_table[j].flag=1; break; } else j++; }//如果j<10就分配成功 if(j!=10){ printf("分配成功n"); }else{//如果分配不成功,那么还回空闲分配区的长度 if(free_table[k].length==0){ free_table[k].length=xk; }else{ free_table[k].length=free_table[k].length+workPcb->length; used_table[j].flag=0; free_table[k].address-=workPcb->length; } printf("分配空间不足"); } }else{ printf("空闲空间不足,失败n"); } } void reclaim(workPcb *J){ int s=0,a=0; double S,L; while(s<=9){ a=strcmp(J->name,used_table[s].name); if(a==0){//找到作业与未找到作业 S=used_table[s].address; L=used_table[s].length; used_table[s].flag=0; int j=-1;//相邻下空闲区栏 int k=-1; double upS,doS;//相邻上空闲区栏 upS=used_table[s].address+used_table[s].length;//应该的上分区和下分区//应该的上分区和下分区 int q=0; while(q<=9){//判断有没有上下分区 if(free_table[q].address==upS){ k=q; } if(free_table[q].address+free_table[q].length==S){ j=q; } q++; } if(k!=-1){//存在上分区 if(j!=-1){//两个分区都存在 free_table[k].length=L+free_table[k].length+free_table[j].length; free_table[k].address-=L+free_table[j].length; free_table[j].flag=0; printf("回收成功"); } else{//只存在上分区 free_table[k].length=L+free_table[k].length; free_table[k].address-=L; printf("回收成功"); } }else{ if(j!=-1){//只存在下分区 free_table[j].length=L+free_table[j].length; printf("回收成功"); }else{//哪个分区都不存在 int t=0; while(t<=9){//寻找一块分配表里的新地方 if(free_table[t].flag==0){ break; } t++; } if(t==10){ used_table[s].flag=1; printf("作业回收失败,空闲分区表不足"); }else{//设置属性 free_table[t].address=S; free_table[t].length=L; free_table[t].flag=1; printf("回收成功"); } } } break;//找到了就break了 }else s++; } if(s==10){ printf("未找到作业"); } } int main(){ int jud=1; int choice=3; printf("欢迎进入作业分配与回收的程序,1为分配,2为回收,3退出程序,4查看空闲表和已分配表n"); scanf("%d",&choice); workPcb workPcb;//一个作业 free_table[0].address=10*2*2*2*2*2*2*2*2*2*2;//除去了操作系统后的低地址 free_table[0].length=freeArea;//初始化空闲表 free_table[0].flag=1;//空闲区1代表可分配 for(int i=0;i<=9;i++){ used_table[i].flag=0; } //初始化已分配表 已分配表0代表空 while(jud){ switch(choice){ case 1:{ printf("请输入作业名,作业长度n"); scanf("%s%lf",&workPcb.name,&workPcb.length);//填写作业名与长度 printf("作业名:%s作业大小:%lfn",workPcb.name,workPcb.length); distribution(&workPcb); break; } case 2:{ printf("请输入作业名n"); scanf("%s",&workPcb.name);//填写作业名与长度 reclaim(&workPcb); break; } case 3:{ jud=0; printf("拜拜"); break; } case 4:{ printf("------------空闲表状态n"); for(int i=0;i<=9;i++){ printf("空闲区域开始地址:%lf大小:%lf状态:%dn",free_table[i].address,free_table[i].length,free_table[i].flag); } printf("------------已分配表状态n"); for(int i=0;i<=9;i++){ printf("已分配区域作业名:%s开始地址:%lf大小:%lf状态:%dn",used_table[i].name,used_table[i].address,used_table[i].length,used_table[i].flag); } break; } default:{ printf("输入有错误,请重试n"); } } if(jud!=0){ printf("欢迎进入作业分配与回收的程序,1为分配,2为回收,3退出程序,4查看作业状态n"); scanf("%d",&choice); } } return 0; //进行分配任务 }



