一、设计目标

使用 C++编程实现动态分区分配存储管理,解决存储分配时多道程序之间如何共享主存的存储空间的问题。

二、算法原理

1.首次适应算法
将空闲分区链以地址递增的顺序连接;在进行内存分配时,从链首开始顺
序查找,直到找到一块分区的大小可以满足需求时,按照该作业的大小,从该 分区中分配出内存,将剩下的空闲分区仍然链在空闲分区链中。
2.循环首次适应算法
分配内存时不是从链首进行查找可以分配内存的空闲分区,而是从上一次 分配内存的空闲分区的下一个分区开始查找,直到找到可以为该进程分配内存 的空闲分区。
3.最佳适应算法
将空闲分区链中的空闲分区按照空闲分区由小到大的顺序排序,从而形成 空闲分区链。每次从链首进行查找合适的空闲分区为作业分配内存,这样每次 找到的空闲分区是和作业大小最接近的。
4.最坏适应算法
与最佳适应算法刚好相反,将空闲分区链的分区按照从大到小的顺序排序 形成空闲分区链,每次查找时只要看第一个空闲分区是否满足即可。
5.回收算法
进程结束后,撤销的空闲内存独立存在或与相邻的空闲内存合并。

三、设计思路

内存分配流程图,如图 :


存回收流程图,如图:

四、使用说明

一·项目开发环境
语言:C++
系统环境:macOS BigSur

二·第三方工具使用情况
编译器:Xcode

三·使用方法
1.运行程序;
2.首页菜单请选择要执行的算法,并输入相应代码;
3.进入操作菜单请选择要执行的操作,并输入相应代码;
4.若要输入进程,输入进程名称和大小即可;
5.若要撤销进程回收空间,输入进程名称即可;
6.输出所有空闲分区,会输出显示空闲分区的起始地址、大小、结束地址;
7.输出所有已分配分区, 会输出显示空闲分区的名称、起始地址、大小、结束地址;
8.若要输入进程自动产生进程分配空间,选择“2.自动产生进程分配空间”,会自动生成一个进程,包括进程的名称、大小;
9.若要读取文件产生进程分配空间,选择“3.文件产生进程分配空间”,会从文件读取一个进程,包括进程的名称、大小;
10.在操作菜单内,可以选择“7.退出选择其他算法”,并输入相应代码,退出到主菜单可再选择其他算法;
11.首页菜单选择“5.退 出”可结束程序。

五、测试用例

1.首次适应算法
运行程序,键入1,选择首次适应算法;键入1,输入进程分配空间;输入进程名:a,大小:10;键入5,输出所有空闲分区预期结果; 键入6,输出所有已分配分区。

可以得出:
首次适应是从链首开始顺序查找,直到找到一块分区的大小可以满足需求时,按照该作业的大小,从该分区中分配出内存。

2.循环首次适应算法
键入7,退出当前算法,继续运行程序。键入2,选择循环首次适应算法;键入1,输入进程分配空间;输入进程名:b,大小:10;再键入1,输入进程分配空间;输入进程名:c,大小:10;键入5,输出所有空闲分区预期结果; 键入6,输出所有已分配分区。

可以得出:
第二次分配c并没有分配进第一个空闲内存。分配内存是从上一次分配内存的空闲分区的下一个分区开始查找,直到找到可以为该进程分配内存的空闲分区。

3.最佳适应算法
键入7,退出当前算法,继续运行程序。键入3,选择最佳适应算法;键入1,输入进程分配空间;输入进程名:d,大小:20;键入5,输出所有空闲分区预期结果; 键入6,输出所有已分配分区。

可以得出:
分配d并没有分配进第二个空闲内存,而是选择第四个,满足作业大小又是最小的空闲内存。最佳即每次找到的空闲分区是和作业大小最接近的。

4.最坏适应算法
键入7,退出当前算法,继续运行程序。键入4,选择最坏适应算法;键入1,输入进程分配空间;输入进程名:e,大小:10;键入5,输出所有空闲分区预期结果; 键入6,输出所有已分配分区。

可以得出:
分配e并没有分配进第一个空闲内存,而是选择第二个,最大的空闲内存。最佳即每次找到的空闲分区是和作业大小最接近的。

5.回收算法
键入4,进程撤销回收空间c。键入4,进程撤销回收空间e。

可以得出:
撤销回收区间会将周围空闲区间合并。

6.自动产生进程分配空间
运行程序,键入1,选择首次适应算法;键入2,自动产生进程分配空间;键入5,输出所有空闲分区预期结果; 键入6,输出所有已分配分区。

7.自动产生进程分配空间
运行程序,键入3,选择最优适应算法;键入3,读取“1.txt”文件产生进程分配空间;键入5,输出所有空闲分区预期结果; 键入6,输出所有已分配分区。

六、程序源代码

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <fstream>
#include <iostream>
typedef struct readyque
{char name[3];int size;
}readyque,*readyqueue;typedef struct idlyspace
{int from;int size;idlyspace * next;
}idlyspace,*idly;typedef struct busyspace
{int from;readyque r;busyspace * next;
}busyspace,*busy;idly Is,Is2;
busy Bs;
int AUTO=0;
readyque Scanf()
{int i=0;char R[26]={'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};readyque t;for(int b=0;b<3;b++){t.name[b]=0;}if(AUTO==0){printf("请输入进程名:");scanf("%s",t.name);printf("输入进程申请空间大小:");scanf ("%d",&t.size);}else if(AUTO==1){for(i=0;i<2;i++){t.name[i]=R[rand()%25+0];}t.size=rand()%100+1;printf("随机产生进程名为: ");for(i=0;i<3;i++){printf("%c",t.name[i]);}printf("\n");printf("随机产生空间大小: %d\n",t.size);}else if(AUTO==2){t.name[0]='R';freopen("1.txt","r",stdin);scanf("%d",&t.size);fclose(stdin);freopen("con","r",stdin);printf("随机产生进程名为:%c\n",t.name[i]);printf("读取产生空间大小: %d\n",t.size);freopen("/dev/tty","r",stdin);}return t;
}int FF()//首次适应算法
{int t=0;readyque D;D=Scanf();idly l=Is;int mt=256;busy b=Bs;idly min=NULL;while(l)//寻找空闲表中大小满足申请进程所需大小并且起址最小的空闲结点{if(l==Is && l->size==0){idly ii;ii=l;Is=l->next;free(ii);l=Is;}else if(l->next!=NULL && l->next->size==0){idly ii;ii=l->next;l->next=l->next->next;free(ii);}else if(l->next!=NULL && l->next->next==NULL && l->next->size==0){idly ii;ii=l->next;l->next=NULL;free(ii);}if(D.size<=l->size){if(l->from<mt){mt=l->from;min=l;t=1;}}l=l->next;}if(mt!=256) //如果找到则为进程分配空间{busy j;j=(busy)malloc(sizeof(busyspace));j->from=min->from;for(int i=0;i<10;i++){j->r.name[i]=D.name[i];}j->r.size=D.size;while(b->next){if(b->next->from<j->from)b=b->next;elsebreak;}j->next=b->next;b->next=j;min->from=min->from+D.size;min->size=min->size-D.size;}return t;
}int NF()//循环首次适应算法
{int t=0;readyque D;D=Scanf();int mt=256;idly l=Is2;idly min=NULL;busy b=Bs;while(l)//从上次的位置开始,寻找空闲表中大小满足申请进程所需大小并且起址最小的空闲结点{if(l==Is && l->size==0){idly ii;ii=l;Is=l->next;free(ii);l=Is;}else if(l->next!=NULL && l->next->size==0){idly ii;ii=l->next;l->next=l->next->next;free(ii);}else if(l->next!=NULL && l->next->next==NULL && l->next->size==0){idly ii;ii=l->next;l->next=NULL;free(ii);}if(D.size<=l->size){if(l->from<mt){mt=l->from;min=l;t=1;}}l=l->next;}if(mt!=256) //如果找到则为进程分配空间{busy j;j=(busy)malloc(sizeof(busyspace));j->from=min->from;for(int i=0;i<10;i++){j->r.name[i]=D.name[i];}j->r.size=D.size;while(b->next){if(b->next->from<j->from)b=b->next;elsebreak;}//将申请空间进程插入到已分配链表中j->next=b->next;b->next=j;//修改相应空闲节点的起址和大小min->from=min->from+D.size;min->size=min->size-D.size;Is2=min->next; //ls2 指向修改结点的下一个结点t=1;return t;//退出并返回t}return t;
}int BF()//最优适应算法
{int t=0;readyque D;D=Scanf();idly l=Is;idly min=NULL;int mt=256;busy b=Bs;while(l){if(l==Is && l->size==0){idly ii;ii=l;Is=l->next;free(ii);l=Is;}else if(l->next!=NULL && l->next->size==0){idly ii;ii=l->next;l->next=l->next->next;free(ii);}else if(l->next!=NULL && l->next->next==NULL && l->next->size==0){idly ii;ii=l->next;l->next=NULL;free(ii);}if(D.size<=l->size)//判断进程所申请的大小是否小于空闲区的各结点大小{if(l->size<mt){mt=l->size;min=l;//min 指向空闲区中尺寸最小的结点t=1;}}l=l->next; //l 指向空闲链表下一个结点}if(mt!=256) //找到第一个满足要求的空闲块{busy j;j=(busy)malloc(sizeof(busyspace)); //申请分配用于存放进程的内存空间j->from=min->from;//将第一个满足要求的空闲块(min)的首地址赋给 jfor(int i=0;i<10;i++){j->r.name[i]=D.name[i];}j->r.size=D.size;while(b->next)//按从小到大的顺序查找新进程在已分配区中的位置{if(b->next->from<j->from)b=b->next;elsebreak;}j->next=b->next;b->next=j; //将所输入的进程插入进程链min->from=min->from+D.size; //改变该空闲块的起始地址min->size=min->size-D.size; //改变该空闲块的剩余大小if (min->size==0){min=NULL;free(min);}}return t;
}int WF()//最坏适应算法
{int t=0;readyque D;D=Scanf();idly l=Is;//l 指向空闲链表 ls 头idly min=NULL;int mt=0;busy b=Bs; //b 指向已分配链表 Bs 头//找到空闲分区中大小满足进程的请求且尺寸最大的结点while(l){if(l==Is && l->size==0){idly ii;ii=l;Is=l->next;free(ii);l=Is;}else if(l->next!=NULL && l->next->size==0){idly ii;ii=l->next;l->next=l->next->next;free(ii);}else if(l->next!=NULL && l->next->next==NULL && l->next->size==0){idly ii;ii=l->next;l->next=NULL;free(ii);}if(D.size<=l->size)//判断进程所申请的大小是否小于空闲区的各结点大小{if(l->size>mt){mt=l->size;min=l;//min 指向空闲区中尺寸最大的结点t=1;}}l=l->next; //l 指向空闲链表下一个结点}if(mt!=0) //判断是否找到了空闲区的满足结点{busy j;j=(busy)malloc(sizeof(busyspace));j->from=min->from;for(int i=0;i<3;i++){j->r.name[i]=D.name[i];}j->r.size=D.size;while(b->next) //寻找插入到已分配链表中的位置{if(b->next->from<j->from)b=b->next;elsebreak;}//把此进程结点 j 插入到已分配链表中j->next=b->next;b->next=j;//修改空闲链表的相应结点的参数min->from=min->from+D.size;min->size=min->size-D.size;}return t;
}
int recover()
{readyque D;printf ("请输入想要回收的进程名:");scanf ("%s",D.name);busy b=Bs;idly l=Is;while(b->next){bool yo=1;for(int i=0;i<3;i++){if(b->next->r.name[i]==D.name[i])yo=yo*1;elseyo=0;}if(yo)//如果在已分配链表中,则释放该结点所占空间{int t=b->next->from;int ts=b->next->r.size;if(t==0)//所回收进程在第一个{if(l->from==t+ts)//与空闲结点下邻接{l->size=l->size+ts;l->from=0;busy ta=b->next;//从已分配链表中释放所回收进程b->next=b->next->next;free(ta);return 1;}//与空闲结点不邻接idly tl;tl=(idly)malloc(sizeof(idlyspace));tl->from=0;tl->size=ts;tl->next=l;Is=tl;busy ta=b->next;//从已分配链表中释放所回收进程b->next=b->next->next;free(ta);return 1;}if(t+ts==256)//所回收进程在最后一个{l->size=l->size+ts;if(l->from+l->size==l->next->from)// 所回收进程与空闲结点上邻接{busy ta=b->next;//从已分配链表中释放所回收进程b->next=b->next->next;free(ta);return 1;}//与空闲结点的不邻接idly tl;tl=(idly)malloc(sizeof(idlyspace));tl->from=t;tl->size=ts;while(l){l=l->next;}l->next=tl;busy ta=b->next;//从已分配链表中释放所回收进程b->next=b->next->next;free(ta);return 1;}while(l){if(l->from+l->size==t)//所回收进程与空闲结点的上邻接{l->size=l->size+ts;if(l->from+l->size==l->next->from)// 所回收进程与空闲结点上下都邻接{l->size=l->size+l->next->size;idly tm=l->next;l->next=l->next->next;free(tm);}busy tc=b->next;//从已分配链表中释放所回收进程b->next=b->next->next;free(tc);return 1;}l=l->next;}l=Is;while(l){if(l->from==t+ts)//所回收进程与空闲结点下邻接{l->from=t;l->size=l->size+ts;busy tb=b->next;//从已分配链表中释放所回收进程b->next=b->next->next;free(tb);return 1;}l=l->next;}l=Is;while(l){if(l->from>t+ts)//所回收进程首尾都是被占用的内存,与空闲结点上下都不邻接,空结点在后,则单独成一个空闲结点{idly tl;tl=(idly)malloc(sizeof(idlyspace));tl->from=t;tl->size=ts;tl->next=l;Is=tl;busy tb=b->next;//从已分配链表中释放所回收进程b->next=b->next->next;free(tb);return 1;}else if(l->from+l->size<t)//所回收进程与空闲结点上下都不邻接,空结点在前{idly tl;tl=(idly)malloc(sizeof(idlyspace));tl->from=t;tl->size=ts;tl->next=l->next;l->next=tl;busy tb=b->next;//从已分配链表中释放所回收进程b->next=b->next->next;free(tb);return 1;}l=l->next;}}b=b->next;}printf("没找到这个进程\n");return 0;
}
int Isprint()
{idly I1=Is;printf("\n..............空闲分区说明..............\n");printf(".....起始地址.......大小.......结束地址.......\n");while(I1!=NULL){printf("%10d %10d %10d\n",I1->from,I1->size,I1->from+I1->size);I1=I1->next;}return 0;
}int Bsprint()
{busy B1=Bs->next;printf("\n..............已分配分区说明..............\n");printf(".......名称.......起始地址......大小.......结束地址.......\n");while(B1!=NULL){printf("%10s %10d %10d %10d\n",B1->r.name,B1->from,B1->r.size,B1->from+B1->r.size);B1=B1->next;}return 0;
}int Bsprint2()
{busy B1=Bs->next;printf("\n..............已分配分区说明..............\n");printf(".......名称.......起始地址......大小.......结束地址.......\n");while(B1!=NULL){printf("        ");for(int i=0;i<3;i++){printf("%c",B1->r.name[i]);}printf("%10d %10d %10d\n",B1->from,B1->r.size,B1->from+B1->r.size);B1=B1->next;}return 0;
}int main()
{Is=(idly)malloc(sizeof(idlyspace));Is->from=0;Is->next=NULL;//内存分区idly Im;Im=Is;Is->size=32;Im->next=(idly)malloc(sizeof(idlyspace));Im=Im->next;Im->from=32;Im->size=128;Im->next=(idly)malloc(sizeof(idlyspace));Im=Im->next;Im->from=160;Im->size=64;Im->next=(idly)malloc(sizeof(idlyspace));Im=Im->next;Im->from=224;Im->size=32;Im->next=NULL;Is2=Is;Bs=(busy)malloc(sizeof(busyspace));Bs->next=NULL;int t=0,t1;while(t!=5){printf("\n......................欢迎来到动态分区存储管理系统 ....................\n\n");printf("..........................请选择要执行的算法 :.........................\n");printf("......................... 1.首次适应算法 .............................\n");printf("......................... 2.循环首次适应算法 ..........................\n");printf("..........................3.最优适应算法 .............................\n");printf("......................... 4.最坏适应算法 .............................\n");printf("..........................5.退  出 ..................................\n");printf("....................................................................\n");printf("请输入您的选择 :");scanf("%d",&t);int i=0;if(1<=t&&t<5){while(i!=7){printf("....................................................................\n");printf("..........................操作菜单如下:(请选择) .......................\n");printf("..........................1.输入进程分配空间 ..........................\n");printf("..........................2.自动产生进程分配空间 .......................\n");printf("..........................3.读取文件产生进程分配空间 ....................\n");printf("..........................4.进程撤销回收空间 ..........................\n");printf("..........................5.输出所有空闲分区 ..........................\n");printf("..........................6.输出所有已分配分区 .........................\n");printf("..........................7.退出选择其他算法 ...........................\n");printf("....................................................................\n");scanf("%d",&i);switch(i){case 1:switch(t){case 1:t1=FF();break;case 2:t1=NF();break;case 3:t1=BF();break;case 4:t1=WF();break;default:printf("选择算法错误 \n");return 1;}if(t1)printf("分配空间成功 \n");elseprintf("分配空间失败 \n");break;case 4:t1=recover();if(t1)printf("回收成功 \n");elseprintf("回收失败 \n");break;case 5:Isprint();break;case 6:Bsprint();break;case 2:AUTO=1;switch(t){case 1:t1=FF();break;case 2:t1=NF();break;case 3:t1=BF();break;case 4:t1=WF();break;default:printf("选择算法错误 \n");return 1;}AUTO=0;if(t1)printf("分配空间成功 \n");elseprintf("分配空间失败 \n");break;case 3:AUTO=2;switch(t){case 1:t1=FF();break;case 2:t1=NF();break;case 3:t1=BF();break;case 4:t1=WF();break;default:printf("选择算法错误 \n");return 1;}AUTO=0;Isprint();Bsprint2();i=7;t=5;if(t1)printf("分配空间成功 \n");elseprintf("分配空间失败 \n");break;}}}else if(t==5) break;else printf("请重新输入!\n");}return 0;
}

操作系统:动态内存分区分配算法实现(C++)相关推荐

  1. (王道408考研操作系统)第三章内存管理-第一节5:动态分区分配算法(首次适应、和邻近适应)

    文章目录 一:首次适应算法(First Fit) 二:最佳适应算法(Best Fit) 三:最坏适应算法(Worst Fit) 四:邻近适应算法(Next Fit) 总结 动态分区分配算法:用于研究当 ...

  2. java动态分区分配_操作系统动态分区分配算法课程设计java版解析.doc

    湖 南 文 理 学 院 实 验 报 告 课程名称 操作系统课程设计 实验名称 存储管理--动态分区分配算法的模拟 成绩 学生姓名 曹乐 专业 计算机 班级.学号 13101 18 同组者姓名 实验日期 ...

  3. java动态分区分配算法,操作系统_动态分区分配算法课程设计_java版

    <操作系统_动态分区分配算法课程设计_java版>由会员分享,可在线阅读,更多相关<操作系统_动态分区分配算法课程设计_java版(13页珍藏版)>请在人人文库网上搜索. 1. ...

  4. java动态分区分配_操作系统 动态分区分配算法课程设计 java版.pdf

    操作系统 动态分区分配算法课程设计 java版 湖 南 文 理 学 院 实 验 报 告 课程名称 操作系统课程设计 实验名称 存储管理--动态分区分配算法的模拟 成绩 学生姓名 曹乐 专业 计算机 班 ...

  5. 操作系统(三十六)动态分区分配算法

    3.5 动态分区分配算法 上节讲述了连续分区分配方式中有动态分区分配的方式,如果在动态分区分配算法中有许多空闲分区都满足需求的时候,那该如何分配空间呢,今天来介绍四种分配方法解决这个问题. 目录 3. ...

  6. 基于顺序搜索的动态分区分配算法模拟内存动态分配--最佳适应算法(best fit,BF)

    BF算法.男朋友算法,哈哈 要实现动态分区分配,需要考虑三个方面的问题.分别是数据结构.分区分配算法.分区的分配与回收操作. 首数据结构 这里我们使用的是空闲分区链,采用双向链表表示空闲分区. 具体实 ...

  7. 七、操作系统——动态分区分配算法(详解)

    一.引入 动态分区分配算法:在动态分区分配方式中,当很多个空闲分区都能满足需求时,应该选择哪个分区进行分配? 二.首次适应算法(First Fit) 算法思想:每次都从低地址开始查找,找到第一个能满足 ...

  8. 操作系统【动态分区分配算法——首次适应算法、最佳适应算法、最坏适应算法、临近适应算法】

    学习地址(哔哩哔哩网站--王道论坛):https://www.bilibili.com/video/BV1YE411D7nH?p=37 目录 1.首次适应算法(First Fit) 2.最佳适应算法( ...

  9. 内存动态分区分配算法

    动态分区分配 所谓动态分区分配,就是指内存在初始时不会划分区域,而是会在进程装入时,根据所要装入的进程大小动态地对内存空间进行划分,以提高内存空间利用率,降低碎片的大小 动态分区分配算法有以下四种: ...

最新文章

  1. boolean searching, it is so important for searching your papers
  2. System Center 2012R2之SCVMM云部署SCOM(2-2)
  3. java中什么是底层数据结构_JavaScript 对象的底层数据结构是什么
  4. 张朝阳直播带货首秀 带的不仅是好物而是价值平台
  5. 遍历聚合对象中的元素——迭代器模式(四)
  6. HALCON 21.11:深度学习笔记---设置超参数(5)
  7. Cisco *** 完全配置指南-连载-***概述
  8. 大学生活没钱你会学习还是打工? C2 翻译有感
  9. 【JSP售票系统】JSP+SSH+MSSQL火车票铁路售票系统源码
  10. 12个医学公共数据库
  11. 「大专及以上学历人员必看」学信网电子注册备案表
  12. 北京爷们儿跟北京妞儿 倍儿靠谱儿-----女人篇
  13. win 10系统语言栏不见了怎么办?
  14. Smartbi大数据分析工具有哪些功能?
  15. 蓝桥杯:座次问题(枚举法 回溯) java
  16. 如何VUE写桌面应用(electron)
  17. 如何搭建Hyperledger fabric网络
  18. 电路设计之--钽电容选取
  19. 美元汇率【贪心算法练习题】
  20. C语言设计A与B的区别,C语言辅导 - abc与a=b=c的区别 and something else

热门文章

  1. 比 Bloom Filter 节省25%空间!Ribbon Filter 在 Lindorm中的应用
  2. Linux 终端特殊符号含义大全
  3. pbf文件转换为osm
  4. 前端初学学习进程XII
  5. 接口测试(一)常见接口类型
  6. 布尔教育php分享视频,布尔教育jQuery实战视频资料分享
  7. ★★★★★★布尔教育 视频教程 【好学 推荐学习】 ★★★★★★
  8. java怪物掉落_我的世界地下城boss打法及掉落物品一览
  9. 域名1元价,我也来注册一个
  10. pytorch搭建Resnet50实现狗狗120个品种类的分类