循环首次适应的动态分区分配算法模拟
采用首次适应算法的动态分区分配模拟课程设计实验报告
1 需求分析1)本程序要求实现对内存的动态分配与回收的模拟,同时,在内存的分配时还必须使用首次适应算法,最后,还要显示内存块分配和回收后空闲内存分区链的情况。
2)要实现对作业的内存分配,首先要有一个对作业进行创建和分配内存的模块,其中,该模块在分配内存时要使用首次适应算法;要实现对内存的回收,要有一个内存回收的模块,其中,该模块在回收内存时要考虑内存回收的四种情况;最后,还要有一个能显示内存空闲分区链的情况的模块。
2 概要设计1)首次适应算法的结构如图1:图1 首次适应算法的结构图2)数据结构:struct Fq{int size,o,no;Fq *before,*next;};其中,Fq表示结构体的名字(类型),size表示分区的可用空间大小,o表示该分区的状态(是否已分配),no表示该分区中的作业标志,*before表示该结点的向前指针,*next表示该结点的向后指针。
3)各种函数说明:void alloc(int b,int no,Fq *p);对作业no进行内存分配的功能函数;其中,参数b表示需求的内存大小,参数no表示作业的编号,参数*p表示空闲分区链的第一个非空结点的指针;void free(Fq *c);将地址为c的分区的内存回收;其中,参数*c表示要回收内存的结点;void create(Fq *head);创建新作业的子函数;其中,参数*head表示空闲分区链的链首指针;要配合函数alloc()使用;void cha(Fq *head);查看内存中的空闲分区链的子函数;其中,参数*head表示空闲分区链的链首指针;void hui(Fq *head);回收内存的子函数;其中,参数*head表示空闲分区链的链首指针;要配合函数free()使用;3 运行环境1)操作系统: Windows XP ( 32位 / DirectX 11 )2)电脑: X86 兼容台式电脑处理器: 英特尔 Pentium(奔腾) 双核 E5300 @ 2.60GHz内存: 2 GB4 开发工具和编程语言1)开发工具:Visual C++ 6.0;2)编程语言:C++语言;5 详细设计1)程序结构如图2:图2 程序结构图2)●主菜单模块:void main()//主函数{Fq *head=new Fq;head->next=new Fq;head->next->size=MAXSIZE;head->next->o=0;head->next->next=NULL;int choice=0;do{cout<<"请选择你要进行的操作:"<<endl;cout<<"1、创建新作业 2、查看空闲分区链 3、回收内存空间 0、退出"<<endl;cin>>choice;switch(choice){case 1: create(head);break;case 2: cha(head);break;case 3: hui(head);break;case 0: break;default: cout<<"输入错误!"<<endl;}}while(choice!=0);}●创建新作业模块:void create(Fq *head)//创建作业子函数{Fq *p=head->next;p->before=head;int no=0,b=0;cout<<"请输入要创建的作业的编号:";cin>>no;cout<<"请输入作业的需求空间大小:";cin>>b;alloc(b,no,p);//此处调用功能函数alloc()}●查看空闲分区链模块:void cha(Fq *head)//查看内存中的空闲分区链的子函数{Fq *p=head->next;p->before=head;int i=0;cout<<"空闲分区链的情况为:"<<endl;while(p!=NULL){if(p->o==0){cout<<"空闲分区"<<++i<<" "<<p->size<<"K"<<endl;}p=p->next;}}●回收内存空间模块:void hui(Fq *head)//回收内存的子函数{Fq *p=head->next;p->before=head;int no=0;cout<<"请输入要回收内存的作业号:";cin>>no;while(p!=NULL){if(p->no==no){free(p);//此处调用功能函数free()cout<<"作业"<<no<<"的内存已回收!"<<endl;return ;}else p=p->next;}}●内存分配功能函数模块:void alloc(int b,int no,Fq *p)//对作业no进行内存分配的子函数{while(p!=NULL){if(p->o==1) {p=p->next;}else{if(p->size>b){if(p->size-b<=min_size){p->o=1;p->no=no;}else{Fq *q=new Fq;Fq *r;r=p->before;r->next=q;q->before=r;q->next=p;p->before=q;q->size=b;p->size=p->size-b;q->no=no;q->o=1;}cout<<"内存分配成功!"<<endl;return ;}else p=p->next;}}cout<<"内存分配失败!"<<endl;}●内存回收功能函数模块:void free(Fq *c)//将地址为c的分区内存回收{if(c->before->o==0&&c->next->o==0){Fq *r=c->before,*s=c->next->next;r->size=(r->size+c->size+c->next->size);r->next=s;if(s!=NULL) s->before=r;}if(c->before->o==0&&c->next->o!=0){c->before->size=c->before->size+c->size;c->before->next=c->next;c->next->before=c->before;}if(c->next->o==0&&c->before->o!=0){Fq *r=c->next->next;c->size=c->size+c->next->size;c->next=c->next->next;if(r!=NULL) r->before=c;c->o=0;}else c->o=0;}6 调试分析1)内存分配功能函数模块:刚开始对作业分配内存时,只是将空闲分区的大小以及前后向指针进行修改,而没有对分配给作业的内存进行设置;这样,尽管内存的空闲分区大小已经变小,但是,以后却无法对已分配的内存空间以及作业进行修改;于是,我经过思考后,决定将分配给作业的内存空间也设置为一个分区,只不过不是空闲的分区,通过状态标识符o来与空闲分区进行区别。
循环首次适应的动态分区分配算法模拟
循环首次适应的动态分区分配算法模拟1.初始化内存空间为一个整体的空闲块。
2.当进程请求内存空间时,多次内存空闲块的循环链表,直到找到一个合适大小的空闲块为止。
3.如果找到了合适的空闲块,则将其划分为两个部分,一个部分给予进程使用,另一个部分保留为新的空闲块。
4.如果未找到合适的空闲块,则表示内存空间不足,需要进行深度缺页异常处理。
以下是一个循环首次适应算法的模拟过程:1.假设一个内存空间大小为1000KB,初始时为一个整体的空闲块。
2.进程A请求100KB的内存空间,开始内存空闲块链表。
3.如果找到合适的空闲块(大小≥100KB),则将其划分为两个部分,一个部分分配给进程A,另一个部分保留为新的空闲块。
4.进程B请求200KB的内存空间,继续内存空闲块链表。
5.如果找到合适的空闲块(大小≥200KB),则将其划分为两个部分,一个部分分配给进程B,另一个部分保留为新的空闲块。
6.进程C请求150KB的内存空间,继续内存空闲块链表。
7.找到合适的空闲块(大小≥150KB),将其划分为两个部分,一个部分分配给进程C,另一个部分保留为新的空闲块。
8.进程D请求300KB的内存空间,继续内存空闲块链表。
但此时已经循环了一次,仍未找到合适的空闲块。
9.进行深度缺页异常处理,即向操作系统申请更多的内存空间。
10.操作系统分配一块500KB的空闲块给进程D。
11.继续内存空闲块链表,找到合适的空闲块(大小≥300KB)。
12.将其划分为两个部分,一个部分分配给进程D,另一个部分保留为新的空闲块。
13.进程E请求250KB的内存空间,继续内存空闲块链表。
14.找到合适的空闲块(大小≥250KB),将其划分为两个部分,一个部分分配给进程E,另一个部分保留为新的空闲块。
15.当所有进程运行完毕后,剩余的空闲块可以继续加入链表,供下一次的分配请求使用。
总结起来,循环首次适应算法通过循环链表合适大小的空闲块来满足进程的内存需求,能够最大限度地利用内存空间,避免了内存碎片的产生。
最好适应动态分区分配算法模拟
最好适应动态分区分配算法模拟动态分区分配算法是操作系统中的一种管理内存分配的方法,它可以根据实际需求动态地分配和回收内存。
在动态分区分配算法中,内存被划分为多个较小的区域,每个区域可以被分配给一个进程使用。
当一个进程结束后,它所占用的内存可以被回收,并重新分配给其他进程使用。
以下是一个模拟动态分区分配算法的例子。
假设系统中有4个进程需要申请内存空间,它们的大小分别是:P1(100KB)、P2(200KB)、P3(400KB)、P4(300KB)。
本例中我们采用首次适应算法(First Fit)来模拟动态分区分配。
首次适应算法是指内存分区按大小顺序排列,当有一个进程需要内存分配时,系统从低地址到高地址进行,找到一个能满足所需大小的内存分区即可。
以下是该算法的详细步骤:1.初始化内存分区列表。
假设系统中的内存总大小为1000KB,起始地址为0KB,结束地址为1000KB。
此时内存分区列表为空。
2.进程P1申请100KB的内存空间。
内存分区列表,找到第一个大小大于等于100KB的空闲分区,假设为Q1(大小为200KB)。
将分区Q1划分为两个部分:一个部分给进程P1使用,大小为100KB;另一个部分留作未分配区,大小为100KB。
更新内存分区列表,添加两个分区:分区Q1(已分配给P1)和分区Q2(未分配区,大小为100KB)。
此时内存分区列表为:Q1(100KB,已分配给P1)、Q2(100KB,未分配区)。
3.进程P2申请200KB的内存空间。
内存分区列表,找到第一个大小大于等于200KB的空闲分区,假设为Q3(大小为400KB)。
将分区Q3划分为两个部分:一个部分给进程P2使用,大小为200KB;另一个部分留作未分配区,大小为200KB。
更新内存分区列表,添加两个分区:分区Q3(已分配给P2)和分区Q4(未分配区,大小为200KB)。
此时内存分区列表为:Q1(100KB,已分配给P1)、Q2(100KB,未分配区)、Q3(200KB,已分配给P2)、Q4(200KB,未分配区)。
实验五动态分区分配算法的模拟
实验五动态分区分配算法的模拟为了更好地理解动态分区分配算法的工作原理,我们可以进行一次模拟实验。
在实验中,我们将模拟一个内存分区,并使用动态分区分配算法来管理这些分区。
首先,让我们定义一个内存大小为1000字节的分区。
我们假设这个内存中包含几个已分配的分区和几个空闲的分区。
我们使用首次适应算法来进行分区的首次适应分配。
首先,我们将整个内存空间标记为空闲状态,并创建一个初始的空闲链表。
我们假设初始时只有一个空闲分区,大小为1000字节,起始地址为0。
现在,假设有一个进程请求分配一个250字节大小的内存空间。
我们首先检查空闲链表,找到一个大小大于等于250字节的空闲分区。
在这种情况下,我们发现第一个空闲分区的大小是1000字节,所以我们将它拆分成250字节的已分配分区和750字节的空闲分区。
我们在已分配分区上标记一个进程编号,并将空闲分区加入空闲链表。
接下来,假设我们的进程需要申请500字节的内存空间。
在这种情况下,我们需要查找一个大小大于等于500字节的空闲分区。
我们发现第一个可用的空闲分区大小是750字节,我们将它拆分为已分配的500字节和剩余的250字节的空闲分区。
然后,我们假设有进程释放了先前分配的250字节的内存空间。
当一个进程释放分配的内存空间时,我们需要合并相邻的空闲分区。
在这种情况下,释放的分区位于地址0,大小为250字节,并且其下一个分区是地址500,大小为500字节的空闲分区。
因此,我们将这两个分区合并为一个大小为750字节的空闲分区。
接下来,我们假设另一个进程将请求600字节的内存空间。
根据首次适应算法,我们将在第一个满足条件的空闲分区进行分配。
在这种情况下,我们将分配200字节的空闲分区和分配400字节的空闲分区拆分为600字节的已分配分区和空闲分区。
最后,假设一个进程请求200字节的内存空间。
根据首次适应算法,我们在第一个满足条件的空闲分区进行分配。
在这种情况下,我们将250字节的空闲分区拆分为200字节的已分配分区和50字节的空闲分区。
动态分区分配方式的模拟实验报告
if(L[i].rom-T[k].rom>Size)
{
L[i].sad=L[i].sad+T[k].rom;
L[i].rom=L[i].rom-T[k].rom;
L[i].state=1;
T[k].sad=L[i].sad-T[k].rom;
printf("内存分配成功!\n作业申请空间为%d\n起始地址为%d\n",T[k].rom,T[k].sad);
2. 给出初始状态、可用内存空间、请求序列,分别采用首次适应算法和最佳适应算法进行内存块的分配和回收,要求每次分配和回后显示出空闲内存分区链的情况(共有多个空闲分区,每个空闲分区的大小分别为多大)。
4.实验原理或流程图
首次适应算法(First-fit):当要分配内存空间时,就查表,在各空闲区中查找满足大小要求的可用块。只要找到第一个足以满足要球的空闲块就停止查找,并把它分配出去;如果该空闲空间与所需空间大小一样,则从空闲表中取消该项;如果还有剩余,则余下的部分仍留在空闲表中,但应修改分区大小和分区始址。
{
printf("请输入第%d个分区的信息:\n",i);
cin>>L[i].rom>>L[i].sad;
L[i].id=i;
L[i].state=0;
}
printf("输入完毕,当前空闲分区表状态为:\n");
print();
printf("请输入不再切割的剩余空间的大小:\n");
cin>>Size;
{
int id;///空闲分区编号
int sad;///空闲分区首地址
int rom;///空间
计算机操作系统实验报告动态分区分配方式的模拟
计算机操作系统实验报告姓名:班级:学号:题目:动态分区分配方式的模拟实习内容简要描述本次实验要完成两部分内容:一是用C语言实现对采用首次适应算法和最佳适应算法的动态分区分配过程ALLOCo和回收过程FREE(),其中空闲分区由空闲分区链来管理,进行分配时,系统优先使用空闲区底端空间。
二是假设初始状态下,可用内存空间为640KBO按照题目要求的作业顺序,以及各个作业分配和回收的内存空间。
分别采用首次适应法和最佳适应法,对内存进行分配和回收,要求每次分配和回收后显示空闲内存分区链的情况。
实验分析算法介绍本次实验通过用C语言进行编程并调试、运行,形象地表现出动态分区的分配方式,直观地展现了首次适应算法和最佳适应算法对内存的释放和回收方式之间的区别。
加深了我们对两种算法优缺点的理解,帮助我们了解一些数据结构和分配算法,进一步加深我们对动态分区存储器管理方式及其实现过程的理解。
主要的问题在于,如何解决两种算法对内存的释放和回收空间的表示。
动态分区分配:又称为可变分区分配,这种分配方式并不事先先将主存划分成一块块的分区,而是在作业进入主存时,根据作业的大小动态地建立分区。
并使分区的大小正好适应作业的需要。
因此系统中分区的大小是可变的,分区的数目也是可变的。
分区分配算法:(两者的空闲块链接方式不冋)①首次适应法:为作业选择分区时总是按地址从高到低搜索,只要找到可以容纳该作业的空白块,就把该空白块分配给该作业。
特点:优先利用内存中底地址部分的空闲分区(将所有空闲区,按其地址递增的顺序链接)②最佳适应算法:接到内存申请时,在空闲块表中找到一个不小于请求的最小空块进行分配;为作业选择分区时总是寻找其大小最接近于作业所要求的存储区域。
特点:用最小空间满足要求(将所有空闲区,按其大小递增的顺序联接成空闲区链)结果分析(思考题解答;错误原因分析)间的分配和回收。
思考题解答:1、首次适应算法分配时从表头指针开始查找可利用空间表,将找到的第一个大小不小于“请求”的空闲块的一部分分配给用户。
动态分区分配方式模拟
动态分区分配方式模拟动态分区分配方式的核心思想是将内存划分为若干个不同大小的分区,每个分区可以用来存放一个进程或作为一部分进程的存储区域。
当一个进程需要分配内存时,系统会根据进程的需要选择一个合适大小的空闲分区分配给该进程。
当进程执行完毕后,系统会回收其占用的内存分区,再次将其标记为空闲分区。
首次适应算法(First Fit)是最简单的动态分区分配算法之一、它从内存的起始位置开始,寻找第一个满足进程需要的空闲分区,然后将该分区分配给进程。
首次适应算法的优点是实现简单,且内存利用率较高。
然而,它也有一些缺点,比如容易产生碎片,导致内存的利用率下降。
最佳适应算法(Best Fit)是根据进程需要的内存大小,选择最小的满足条件的空闲分区进行分配。
最佳适应算法可以最大限度地减少碎片的产生,提高内存的利用率。
但是,最佳适应算法的缺点是实现较为复杂,同时由于选择最小的分区进行分配,会导致大量的碎片出现。
最坏适应算法(Worst Fit)与最佳适应算法相反,它选择最大的满足进程需要的空闲分区进行分配。
最坏适应算法的优点是可以减少大型进程的外部碎片,但由于选择最大的分区进行分配,会导致更多的碎片产生。
为了更好地理解动态分区分配方式,我们可以通过一个简单的模拟实例来进行说明。
假设有一块内存大小为1MB,现有以下三个请求需要进行内存分配:1.进程A需要200KB的内存;2.进程B需要400KB的内存;3.进程C需要600KB的内存。
首次适应算法:首先,进程A需要200KB的内存,首次适应算法从内存起始位置开始寻找空闲分区,找到一个大小符合要求的空闲分区,将其分配给进程A。
然后,进程B需要400KB的内存,首次适应算法会从上次分配的位置开始,找到一个大小满足要求的空闲分区,并将其分配给进程B。
最后,进程C需要600KB的内存,首次适应算法会继续从上次分配的位置开始,但发现没有足够的空闲分区,分配失败。
最佳适应算法:最佳适应算法需要对所有空闲分区进行排序,按照分区大小的升序排列。
(完整word版)动态分区分配方式模拟
使用动态分区分配方式的模拟1内容(1)用C语言分别实现采用首次适应算法和最佳适应算法的动态分区分配过程alloc( )和回收过程free( )。
其中,空闲分区通过空闲分区链来管理:在进行内存分配时,系统优先使用空闲区低端的空间。
(2)假设初始状态下,可用的内存空间为640KB,并有下列的请求序列:•作业1申请130KB。
•作业2申请60KB。
•作业3申请100KB。
•作业2释放60KB。
•作业4申请200KB。
•作业3释放100KB。
•作业1释放130KB。
•作业5申请140KB。
•作业6申请60KB。
•作业7申请50KB。
•作业6释放60KB。
请分别采用首次适应算法和最佳适应算法,对内存块进行分配和回收,要求每次分配和回收后显示出空闲分区链的情况。
2、示例程序://Tittle: 使用动态分区算法的模拟//author: XuYongzhen#include <stdio.h>#include <stdlib.h>#include <malloc.h>#include <iostream>using namespace std;typedef struct DuLNode{struct DuLNode *prior;struct DuLNode *next;int address;int jsize;int jnumber;//显示分区被那个作业占用,显示零则为空闲分区;}DuLNode,*DuLinkList ;void CreatList(DuLinkList &L){DuLinkList p=(DuLinkList)malloc(sizeof(DuLNode));L->next=p;L->jnumber=100;//为释放头结点后面的结点空间做统一化处理p->prior=L;p->next=NULL;p->jsize=600;p->address=0;p->jnumber=0;}void RequestList(DuLinkList &L,int job,int size){cout<<"作业"<<job<<"申请"<<size<<"KB的空间"<<endl;DuLinkList p=L->next;while((p->jnumber>0||p->jsize<size)&&p)p=p->next;if(p==NULL)cout<<"没有适合的空间分配"<<endl;else{DuLinkList s=(DuLinkList)malloc(sizeof(DuLNode));s->prior=p->prior;p->prior->next=s;s->next=p;p->prior=s;s->jnumber=job;s->jsize=size;s->address=p->address;p->address=p->address+s->jsize;p->jsize=p->jsize-s->jsize;DuLinkList t=L->next;while(t){if(t->jnumber==0)cout<<"空闲分区:始址="<<t->address<<"大小="<<t->jsize<<endl;elsecout<<"已分配的分区:作业号="<<t->jnumber<<"始址="<<t->address<<"大小="<<t->jsize<<endl;t=t->next;}//whilecout<<endl;}//else}//RequestListvoid FreeList(DuLinkList &L,int job){cout<<"作业"<<job<<"释放"<<endl;DuLinkList p=L->next;while(p->next&&p->jnumber!=job)p=p->next;if(p->prior->jnumber==0 && p->next->jnumber==0){//p的前后都是空闲分区,则合并三者DuLinkList s=p->next;DuLinkList q=p->prior;p->prior->next=p->next;p->next->prior=p->prior;s->prior->next=s->next;s->next->prior=p->prior;q->jsize=p->jsize+s->jsize+q->jsize;}if(p->prior->jnumber==0 && p->next->jnumber!=0){//回收区与插入点的前一个分区相临接DuLinkList q=p->prior;p->prior->next=p->next;p->next->prior=p->prior;q->jsize=p->jsize+q->jsize;}if(p->prior->jnumber!=0 && p->next->jnumber==0){//回收区与插入点的后一个分区相临接DuLinkList q=p->next;p->prior->next=p->next;p->next->prior=p->prior;q->address=p->address;q->jsize=p->jsize+q->jsize;}if(p->prior->jnumber!=0 && p->next->jnumber!=0)//回收区去插入点前后的两个空闲分区都不相临接p->jnumber=0;DuLinkList t=L->next;while(t){if(t->jnumber==0)cout<<"空闲分区:始址="<<t->address<<"大小="<<t->jsize<<endl;elsecout<<"已分配的分区:作业号="<<t->jnumber<<"始址="<<t->address<<"大小="<<t->jsize<<endl;t=t->next;}cout<<endl;}void main(){DuLinkList L=(DuLinkList)malloc(sizeof(DuLNode));CreatList(L);RequestList(L,1,130);RequestList(L,2,60);RequestList(L,3,100);FreeList(L,2);RequestList(L,4,200);FreeList(L,3);FreeList(L,1);RequestList(L,5,140);RequestList(L,6,60);RequestList(L,7,50);FreeList(L,6);}。
动态分区分配方式的模拟 (2)
p->n=p->n+1;
}
printf("内存分配成功!\n");
return 1;
}
p = p->nxt;
}
printf("找不到合适的内存分区,分配失败...\n");
return 0;
}
//最佳适应算法
int bestFit(int task = Busy;
tar->taskId = taskId;
p->n=p->n+1;
}
printf("内存分配成功!\n");
return 1;
} else {
//找不到合适的空闲分区
printf("找不到合适的内存分区,分配失败...\n");
return 0;
}
}
//回收内存
int freeSubArea(int taskId)
p = p->pre;
p->size += pp->size;
p->nxt = pp->nxt;
if(pp->nxt != NULL) {
pp->nxt->pre = p;
}
free(pp);
} else {
//情况4:上下分区均不用合并
p->state = Free;
p->taskId = -1;
pp->nxt->pre = p;
}
free(pp);
} else if((p->pre != &subHead && p->pre->state == Free)
模拟动态分区首次适应分配和回收算法
模拟动态分区首次适应分配和回收算法1. 引言在操作系统中,内存管理是一个至关重要的部分。
动态分区分配是一种常见的内存分配方式,而首次适应算法是其中的一种经典算法。
本文将通过模拟的方式,深入探讨模拟动态分区首次适应分配和回收算法的原理、特点和优缺点,以及对该算法的个人观点和理解。
2. 模拟动态分区首次适应分配算法首次适应算法是一种简单而直观的内存分配算法。
在该算法中,系统会将内存分割成多个大小不等的空闲分区,并根据进程请求的内存大小,选择第一个能满足要求的空闲分区进行分配。
这样做的好处是能够尽快地找到合适大小的内存空间,但也容易造成内存碎片的产生。
为了更加直观地理解首次适应分配算法,我们可以通过一个模拟实例来说明。
假设系统的内存空间大小为100KB,初始时有一块大小为40KB的进程被分配了内存空间。
此时,系统剩余的内存空间大小为60KB。
又来了一个大小为20KB的进程请求内存,根据首次适应算法,系统会分配空闲分区中第一个能满足要求的内存空间,因此会将这个20KB的进程分配到剩余空间大小为60KB的位置。
以此类推,直到没有符合要求的空闲分区为止。
3. 模拟动态分区首次适应回收算法在动态分区管理中,除了内存分配,内存回收同样是至关重要的。
首次适应回收算法的原理是当一个进程释放了分配给它的内存空间后,系统会对相邻的空闲分区进行合并,以尽量减少内存碎片的产生,从而提高内存利用率。
继续之前的模拟实例,假设40KB的进程释放了它所占用的内存空间,系统会将释放的内存空间与相邻的60KB的空闲分区进行合并,得到一块大小为100KB的连续空闲分区。
这样,系统就能够更好地满足后续进程的内存分配请求。
4. 模拟实例总结通过以上模拟实例,我们可以更直观地理解动态分区首次适应分配和回收算法的工作原理。
首次适应算法简单直观,能够快速找到符合要求的内存空间,但容易产生内存碎片。
而首次适应回收算法能够有效减少内存碎片,提高内存利用率。
操作系统内存动态分配模拟算法
操作系统内存动态分配模拟算法操作系统内存动态分配是操作系统对内存资源进行合理分配和管理的一种技术。
其实质是根据程序的需求,将物理内存分割成若干个大小相等的内存块,然后将程序的逻辑地址空间映射到这些内存块上。
这样,程序将感觉到它拥有整个内存的使用权,而实际上其实只能访问到被映射的内存块。
常见的内存动态分配算法包括首次适配、最佳适配和最坏适配等。
下面将分别介绍这几种算法的原理和优缺点。
首次适配算法(First Fit)是指将第一个满足程序要求大小的空闲内存块分配给程序。
这种算法的实现较为简单,仅需遍历整个内存块链表即可。
然而,由于首次适配分配的是满足要求的第一个内存块,因此可能会导致形成大量的碎片空间,从而减少了可用内存的利用率。
最佳适配算法(Best Fit)是指在所有满足程序要求大小的空闲内存块中选择最小的一个分配给程序。
这种算法比首次适配算法更加合理,能够充分利用碎片空间,提高内存的利用率。
然而,由于需要遍历所有的空闲内存块,因此算法的性能相对较低。
最坏适配算法(Worst Fit)是指在所有满足程序要求大小的空闲内存块中选择最大的一个分配给程序。
这种算法的主要目的是为了降低外部碎片的产生。
但是,由于内存块的分配更加倾向于大的空闲块,因此可能导致大量的小碎片空间,从而增加了再分配的开销和运行时的内存碎片整理。
此外,还有一种较为常见的内存动态分配算法是循环首次适配算法(Circular First Fit)。
其与首次适配算法类似,但其从上一次分配的位置开始,不会每次都从链表的头部开始,从而缩小了的范围,提高了算法的性能。
总结来说,不同的内存动态分配算法有着各自的优缺点。
首次适配算法简单易实现,但会产生大量碎片空间;最佳适配算法能够提高内存利用率,但性能较低;最坏适配算法能够降低外部碎片的产生,但会增加小碎片空间。
因此,在实际应用中,需要根据具体的场景和需求选择合适的算法来进行内存动态分配,以达到最优的资源利用效率。
采用首次适应算法实现动态分区分配过程的模拟
p = head;
while (p != NULL) {
//根据作业号查找要释放的作业
if (p->id == id) {
p->id = -1;
p->isallocated = no;
//Hale Waihona Puke 果此作业前面还有空闲分区,则与之合并
if (p->prev != NULL && p->prev->isallocated == no) {
实验四
实验
采用首次适应算法实现动态分区分配过程的模拟
实验
用C语言编程,实现采用首次适应算法的动态分区分配过程。
实验内容:
(1)空闲分区通过空闲分区链来管理;进行内存分配时,系统优先使用空闲区低端的空间。
(2)假设初始状态下可用的内存空间为640KB,并有下列的请求序列:
作业1申请130KB
作业2申请60KB
p->id = id;//直接修改作业号
p->isallocated = yes;
break;
}
p = p->next;
}
if (p == NULL) {
printf("没有足够的内存可以分配了!\n");
}
}
//释放内存
void returnMemory() {
int id;
Node* p;
printf("请输入要释放内存的作业号:");
p->length -= size;//空闲分区的长度做相应的修改
//判断这块空闲分区是不是第一块分区
【操作系统】分区分配算法(首次适应算法、最佳适应算法)(C语言实现)
【操作系统】分区分配算法(⾸次适应算法、最佳适应算法)(C语⾔实现)【操作系统】分区分配算法(⾸次适应算法、最佳适应算法)(C语⾔实现)(编码⽔平较菜,写博客也只是为了个⼈知识的总结和督促⾃⼰学习,如果有错误,希望可以指出)今天测试,发现⼀点问题:1.最佳插⼊算法:对于插⼊的时候忘记修改temp.next.front的指向2.回收头节点的时候现在多了⼀种判断。
判断头节点的下⼀个是否为空。
对如果不为空⽽且后⾯的空闲的话,做出了处理。
原来则没有这⼀情况。
1.动态分区分配算法:为了实现动态分区分配,通常将系统中的空闲分区链接成⼀个链。
所谓顺序查找是指依次搜索空闲分区链上的空闲分区,去寻找⼀个⼤⼩能满⾜要求的分区。
--------计算机操作系统(第四版)2.动态分区算法主要包括四种:(1).⾸次适应算法(first fit,FF):要求,空闲分区链以地址递增的顺序链接。
每次从链⾸开始,直到找到第⼀个能满⾜要求的空闲分区为⽌。
简单来说,就是,每次都从第⼀个开始顺序查找,找到⼀块区域可以满⾜要求的。
优点:优先利⽤内存中低址部分的空闲分区,从⽽保留了⾼址部分的⼤空闲区,这为以后到达的⼤作业分配⼤的内存空间创造了条件。
缺点:低址部分不断被划分,会留下许多难以利⽤的,很⼩的空闲分区,称为碎⽚。
⽽每次查找⼜都是从低址部分开始的,这⽆疑⼜会增加查找可⽤空闲分区时的开销。
(2).循环⾸次适应算法(next fit,NF):与FF算法区别就是,不是每次都从⾸次开始,⽽是从上次找到的空闲分区的下⼀个空闲分区开始。
(第⼀次查找的话也是从⾸页开始)。
特点:能使内存中的空闲区分布得较均匀。
(3).最佳适应算法(best,BF):将所有空闲分区按照空闲分区容量⼤⼩从⼩到⼤的顺序连接起来,形成⼀个空闲分区链。
即,每次都是找空间容量不但可以满⾜要求的空闲区,⽽且该空闲分区的容量还要最接近要求的容量⼤⼩。
优点:每次分配给⽂件的都是最合适该⽂件⼤⼩的分区。
动态分区分配方式的模拟实验原理说明
动态分区分配方式的模拟实验原理说明一、引言动态分区分配方式是计算机内存管理中一种常见的分配方式,它将内存按需划分为多个独立的区域,用于分配进程所需的内存空间。
本文将详细探讨动态分区分配方式的原理及其在模拟实验中的应用。
二、动态分区分配方式的原理动态分区分配方式基于内存动态分配,将可用内存划分为多个不连续的分区,每个分区可用于存放一个进程或程序。
此分配方式具有灵活性,能够更好地满足不同程序对内存空间的需求。
2.1 空闲内存分区列表在动态分区分配方式中,操作系统维护一个空闲内存分区列表,记录可供分配的内存空间情况。
列表中的每个分区都有其起始地址和长度。
2.2 分区分配算法动态分区分配方式有多种分区分配算法可供选择,主要包括首次适应算法、最佳适应算法和最差适应算法。
•首次适应算法:从空闲分区列表中找到第一个满足分配要求的分区进行分配。
•最佳适应算法:从空闲分区列表中找到最小的满足分配要求的分区进行分配。
•最差适应算法:从空闲分区列表中找到最大的满足分配要求的分区进行分配。
2.3 分区回收算法当进程结束或释放内存时,操作系统需要将其占用的内存空间回收,归还给空闲内存区。
分区回收算法的目标是尽可能地合并相邻的空闲区域,以最大程度地提供可用内存。
三、动态分区分配方式的模拟实验为了更好地理解和研究动态分区分配方式,可以进行一系列模拟实验。
下面将介绍动态分区分配方式的模拟实验原理及步骤。
3.1 实验原理动态分区分配方式的模拟实验基于以下原理: - 创建一个内存模拟环境,模拟操作系统管理的内存空间。
- 设计一系列测试用例,模拟进程的创建、分配和回收过程。
- 根据所选的分区分配算法和分区回收算法,计算分区分配和回收的效果。
- 比较不同算法在性能方面的差异,并分析其优缺点。
3.2 实验步骤动态分区分配方式的模拟实验包括以下步骤: 1. 初始化内存模拟环境,创建一个空闲分区列表。
2. 设计多个测试用例,包括不同大小和数量的进程。
存储管理动态分区分配算法的模拟
存储管理动态分区分配算法的模拟一(题目: 存储管理--- 动态分区分配算法的模拟二(任务: 设计主界面以灵活选择某算法,且以下算法都要实现:首次适应算法、循环首次适应算法、最佳适应算法;。
三(思想: 对任务进行构思和设想。
(1) 首次适应算法:FF算法要求空闲分区链以地址递增的次序链接。
在分配内存时,从链首开始顺巡查找,直到找到一个大小能够满足要求的空闲分区为止; 然后再按照作业的大小,从该分区中划出一块内存空间分配给请求者,余下的空闲区间仍留在空闲链中。
若从链首直至链尾都不能找到一个能满足要求的分区,则此次内存分配失败,返回。
该算法倾向于优先利用内存中低址部分的空闲分区,从而保留了高址部分的大空闲区。
这给为以后到达的大作业分配大的内存空间创造了条件。
(2) 循环首次适应算法该算法是由首次适应算法演变而成的。
在为进程分配内存空间时,不再是每次都从链首开始查找,而是从上次找到的空闲分区的下一个空闲分区开始查找,直至找到一个能满足要求的空闲分区,从中划出一块的请求大小相等的内存空间分配给作业。
为实现该算法,应设置一起始查找指针,用于指示下一次起始查询的空闲分区,并采用循环查找方式,即如果最后一个( 链尾)空闲分区的大小仍不能满足要求,则返回到第一个空闲分区,比较大小是否满足,找到后,应调整起始查询指针。
(3) 最佳适应算法是将最小的空闲分区分配给作业,避免"大材小用"。
为了加速寻找,该算法要求将所有的空闲分区按照某容量以从小到大的顺序形成一空闲分区链。
这样,第一次找到的能满足要求的空闲区,必然是最佳的。
(4) 内存回收:将释放作业所在内存块的状态改为空闲状态,删除其作业名,设置为空。
并判断该空闲块是否与其他空闲块相连,若释放的内存空间与空闲块相连时,则合并为同一个空闲块,同时修改分区大小及起始地址。
四(目的: 在构思中提出要达到的目的。
(1) 按照首次适应算法对内存进行分配,得到(2) 按照循环首次适应算法对内存(3) 按照最佳适应算法对内存进行分配(4) 在作业完成时,释放作业所在内存块,使其能够再次被利用五(方案: 对构思的细化,提出粗略的方案。
计算机操作系统课程设计报告《存储管理——动态分区分配算法的模拟》
《计算机操作系统》课程设计题目:存储管理——动态分区分配算法的模拟专业:软件工程年级:2012级小组成员:指导教师:时间:地点:2012年5 月目录目录 (1)概述 (3)2. 课程设计任务及要求 (3)2.1 设计任务 (3)2.2 设计要求 (3)2.3 课程设计任务安排 (3)3. 算法及数据结构 (4)3.1算法的总体思想(流程) (4)3.2首次适应算法 (4)3.2.1 功能 (4)3.2.2 数据结构(包括变量的定义,要注释!) (4)3.2.3 算法(流程图表示,或伪C表示) (5)3.3循环首次适应算法 (6)3.3.1功能 (6)3.3.2 数据结构 (6)3.3.3算法 (7)3.4最佳适应算法 (8)3.4.1功能 (8)3.4.2 数据结构 (8)3.4.3算法 (8)3.5最坏适应算法 (10)3.5.1功能 (10)3.5.2 数据结构 (10)3.5.3算法 (11)4. 程序设计与实现 (12)4.1 程序流程图 (12)4.2 程序代码(要注释) (12)4.3 实验结果 (21)5. 结论 (23)6. 收获、体会和建议。
(23)A的总结: (23)B的总结: (23)7. 参考文献。
(24)概述动态分区分配是根据进程的实际需要,动态地为之分配内存空间,而在分配时,须按照一定的分配算法,从空闲分区表或空闲分区链中选出一分区分配给该作业。
在本实验中运用了五种分配算法,分别是:1.首次适应算法2.循环首次适应算法3.最坏适应算法4.最佳适应算法5. 快速适应算法2. 课程设计任务及要求2.1设计任务要求设计主界面以灵活选择其中算法,5种算法都要求实现。
2.2设计要求1)首先由系统生成当前的内存状态,要求未分配的分区数量不少于3个,且空间大小随机,然后随机生成一个数,表示等待分配进程的大小。
2)然后显示上述算法由用户选择,结果显示分配后的状态。
3. 算法及数据结构3.1算法的总体思想(流程)设计程序模拟四种动态分区分配算法:首次适应算法、循环首次适应算法、最佳适应算法和最坏适应算法的工作过程。
循环优先自适应的动态分区分配算法仿真.doc
循环优先自适应的动态分区分配算法仿真课程设计报告课程设计主题:第一周期自适应的动态分区分配算法仿真专门化;计算机科学与技术等级:XXXX 1月11日,我记录了循环优先自适应算法、循环优先自适应算法、循环优先自适应算法、循环优先自适应算法、循环优先自适应算法、循环优先自适应算法、循环优先自适应算法、循环优先自适应算法、循环优先自适应算法、循环优先自适应算法、循环优先自适应算法、循环优先自适应算法、循环优先自适应算法、循环优先自适应算法、循环优先自适应算法、循环优先自适应算法,循环优先自适应算法、循环优先自适应算法、循环优先自适应算法、循环优先自适应算法、循环优先自适应算法、循环优先自适应算法、循环优先自适应算法、循环优先自适应算法。
3 2.需求分析3 2。
实验指南3 2。
实验指南4。
这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这个想法,这是我第一次能够这样做。
调试结果如下:1 .七、概要、概要、引用、引用、引用、第一适应算法、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环、循环该算法是从第一个自适应算法发展而来的。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
课程设计报告课程设计题目:循环首次适应的动态分区分配算法模拟专业:计算机科学与技术班级:10204102姓名:谱学号: 10204102指导教师:高小辉2013年1月11 日目录一.循环首次适应算法 (3)1. 概述 (3)2.需求分析 (3)二.实验指导 (4)1.基本思想 (4)2.数据结构 (4)三.运行环境 (6)四.流程图 (6)五.循环首次适应算法代码 (5)六.调试结果 (11)七、总结 (14)八.参考文献 (14)一.循环首次适应算法1.概述:该算法是由首次适应算法演变而成的。
在为进程分配内存空间时,不再是每次都从链首开始查找,而是从上次找到的空闲分区的下一个空闲分区开始查找,直至找到一个能满足要求的空闲分区,从中划出一块的请求大小相等的内存空间分配给作业。
为实现该算法,应设置一起始查找指针,用于指示下一次起始查询的空闲分区,并采用循环查找方式,即如果最后一个(链尾)空闲分区的大小仍不能满足要求,则返回到第一个空闲分区,比较大小是否满足,找到后,应调整起始查询指针。
2. 需求分析了解动态分区分配中使用的数据结构和分配算法,并进一步加深对动态分区存储管理方式及其实现过程的理解。
采用首次适应算法的动态分区分配过程alloc()和回收过程free()。
空闲分区通过空闲分区链表来管理,在进行内存分配时,系统优先使用空闲区低端的空间,即每次分配内存空间是总是从低址部分开始进行循环,找到第一个合适的空间,便按作业所需分配的大小分配给作业。
作业完成时,需要释放作业所占空间,此时要考虑到四种情况:(1)回收区与插入点的前一个空闲分区相邻接。
此时将二者合并,修改前一分区的大小。
(2)回收区与插入点的后一空闲分区相邻接,将二者合并,用回收区的首址作为新空闲区的首址。
(3)回收区同时与插入点的前后两个空闲分区相邻接,三者合并,使用前一空闲分区的表项和首址。
(4)回收区单独存在。
二、实验指导1.基本思想动态分区是指系统不预先划分固定分区,而是在装入程序的时候划分内存区域,使得为程序分配的分区大小恰好等于该程序的需求量,且分区的个数是动态的。
显然动态分区有较大的灵活性,较之固定分区能获得好的内存利用率。
2.数据结构动态分区管理可以用两种数据结构实现,一种是已分配区表和空闲区表,也就是用预先定义好的系统空间来存放空间分配信息。
另一种也是最常用的就是空闲链表,由于对分区的操作是动态的,所以很难估计数据结构所占用的空间,而且空闲区表会占用宝贵的系统空间,所以提出了空闲链表的概念。
其特点是用于管理分区的信息动态生成并和该分区在物理地址上相邻。
这样由于可以简单用两个空闲块之间的距离定位已分配空间,不仅节约了系统空间,而且不必维持已分配空间的信息。
本实验是要做一个模拟程序,来模拟动态分区算法的分配和回收过程,并不是真正的去分配和回收内存。
基本的模拟方法有两种:1、先从内存中申请一块存储区,对这块存储区进行模拟的分配和回收活动。
2、不申请存储区,自己定义一块虚拟的存储区,对这块存储区进行模拟的分配和回收活动,分配和回收仅仅是对数据结构的修改而已。
三.运行环境:1.操作系统 WINDOWS XP2.编译软件 Microsoft Visual C++3.电脑配置:主频3.0GHz 内存512MB四.流程图1.程序结构如图:2.首次适应算法的结构如图:五.循环首次适应算法代码#include <iostream>#include <stdlib.h>#include <stdio.h>using namespace std;struct memory{struct memory *former; //前向指针 int address;//地址int num;//作业号int size;//分配内存大小int state;//状态0表示空闲1表示已分配struct memory *next; //后向指针};typedef struct memory MEMORY;MEMORY *mem;const int size_min=10;//内存允许的最小空闲块的大小void init(); //初始化内存块void exec();//执行相应算法void F_F(int); //依次初始化每个作业,并根据相应算法对作业分配内存void alloc(MEMORY *,MEMORY *);//分配内存算法(包括两种不同算法)void free(MEMORY *,int);//首次适应算法回收内存void sort(MEMORY *);//对内存链进行排序void insert(MEMORY *,MEMORY *); //按空间大小将作业顺序插入到内存链void print(MEMORY *);//打印内存链void main(){ //主函数int i=0;while(1){ //选择算法cout<<("\n欢迎进入!");cout<<("\nPlease select a number(1,0)");cout<<("\n 循环首次适应算法");cout<<" 0--中止程序"<<endl;cin>>i;if(i==1){ //首次适应算法cout<<("\n以下为首次适应算法:\n");init();exec();}elseexit(1);}}void init(){ //初始化内存容量mem=new MEMORY;mem->size=640;mem->former=0;mem->next=0;}void exec(){//执行算法while(1){//选择申请或释放内存操作cout<<"**************************"<<endl;cout<<"申请内存请输入作业号(1-6)"<<endl;cout<<"释放内存请输入数字8"<<endl;cout<<"中止程序请输入数字0"<<endl;cout<<"**************************"<<endl;int k;cin>>k;//根据k值选择相应的操作if(k>=1&&k<=7) F_F(k);if(k==8){int m;cout<<"请输入要释放的作业号:";cin>>m; //选择相应的回收算法free(mem,m);}else if(k==0){//回滚到选择算法的步骤break;}}}void F_F(int i){ //依次初始化每个作业,并根据相应算法对作业分配内存int work[]={130,60,100,200,160,60,50};//作业序列,i从1开始(与作业号对应),因此从第一个开始存放作业值,第0个值为0,不是作业cout<<"请输入要作业所需的内存大小:";MEMORY *running;running=(MEMORY *)malloc(sizeof(MEMORY));if(running!=NULL){ running->former=NULL;running->address=0;running->num=i; //i从1开始循环running->size=work[i]; //指定作业大小running->state=0; //作业未分配running->next=NULL;//根据相应算法为作业分配内存,详见alloc函数alloc(mem,running); print(mem); cout<<endl;}elsecout<<"没有足够的内存空间"<<endl;}void print(MEMORY *ptr){ //打印显示内存情况MEMORY *temp;temp=ptr->next;cout<<"\n内存链的状态为:"<<endl;while(temp!=NULL){if(temp->state==0){cout<<"内存空闲 "<<"起始地址为:"<<temp->address<<" 空闲空间大小为:"<<temp->size<<"k";}else{cout<<"内存已分配 "<<"起始地址为:"<<temp->address<<" 分配空间大小为:"<<temp->size<<"k" <<" 运行的作业号:"<<temp->num;}cout<<endl;temp=temp->next;}}void free(MEMORY *ptr,int i){ //首次适应算法作业处理完后释放内存空间MEMORY *previous,*current;previous=ptr; current=previous->next;while(current!=NULL){ //循环直到找到需要释放的作业位置if(current->state==1&¤t->num==i){ break;}previous=current;current=current->next;}if(current==NULL){ cout<<"内存中没有任何作业!!!"<<endl; return; }else if(current->next==NULL){ //当前作业为内存中最后一个作业if(previous->state==0){ //与前一个相邻空闲区合并previous->size=previous->size+current->size;previous->next=NULL;cout<<"作业 "<<(current->num)<<"释放 "<<(current->size)<<"k 的空间"<<endl;print(mem);}else{ //将状态改为0,即为空闲区current->state=0;cout<<"作业 "<<(current->num)<<"释放 "<<(current->size)<<"k 的空间"<<endl;print(mem);}}else if((current->next)->next==NULL)//p6{ //当前作业为倒数第二个作业(此种情况还是要单列出来讨论的否则会出现错误)if(previous->state==0&&(current->next)->state==0) //p7 { //释放的地址空间前后均为空闲区previous->size=previous->size+current->size+(current->next)->size; previous->next=NULL; //与下边else(其他情况的不同之处)cout<<"作业 "<<(current->num)<<"释放 "<<(current->size)<<"k 的空间"<<endl;print(mem);}else if(previous->state==0) //p5{ //释放的地址空间前面有空闲块则把它和前面的合并previous->size=previous->size+current->size;(current->next)->former=previous;previous->next=current->next;cout<<"作业 "<<(current->num)<<"释放 "<<(current->size)<<"k 的空间"<<endl;print(mem);}else if((current->next)->state==0) //p8{ //释放的地址空间后面有空闲块则把它和后面的空闲块合并current->size=current->size+(current->next)->size;current->state=0;current->next=NULL; //与下边else(其他情况的不同之处)cout<<"作业 "<<(current->num)<<"释放 "<<(current->size)<<"k 的空间"<<endl;print(mem);}else{ //释放的地址空间前后都没有空闲块时直接把它的状态改为0current->state=0;cout<<"作业 "<<(current->num)<<"释放 "<<(current->size)<<"k 的空间"<<endl;print(mem);}}else{ //其他情况下(当前作业在链表中间)if(previous->state==0&&(current->next)->state==0) //p7 { //所释放空间前后均为空闲区previous->size=previous->size+current->size+(current->next)->size; ((current->next)->next)->former=previous;previous->next=(current->next)->next;cout<<"作业 "<<(current->num)<<"释放 "<<(current->size)<<"k 的空间"<<endl;print(mem);}else if(previous->state==0) //p5{ //释放的地址空间前面有空闲块则把它和前面的合并previous->size=previous->size+current->size;(current->next)->former=previous;previous->next=current->next;cout<<"作业 "<<(current->num)<<"释放 "<<(current->size)<<"k 的空间"<<endl;print(mem);}else if((current->next)->state==0) //p8{ //释放的地址空间后面有空闲块则把它和后面的空闲块合并current->size=current->size+(current->next)->size;current->state=0;((current->next)->next)->former=current;current->next=(current->next)->next;cout<<"作业 "<<(current->num)<<"释放 "<<(current->size)<<"k 的空间"<<endl;print(mem);}else{ //处理完的作业前后都没有空闲块时直接把它的状态改为0current->state=0;cout<<"作业 "<<(current->num)<<"释放 "<<(current->size)<<"k 的空间"<<endl;print(mem);}}}void alloc(MEMORY *ptr,MEMORY *assign){ //根据算法分配内存(is_optimist状态)if(ptr->next==NULL){ //内存没有作业运行if(ptr->size>=assign->size){ //内存空间大于作业所需空间,为内存分配空间ptr->size=ptr->size-assign->size;assign->state=1;ptr->next=assign;assign->former=ptr;cout<<"作业 "<<(assign->num)<<"申请"<<(assign->size)<<" "<<"k的内存空间"<<endl;}else{cout<<"没有足够的内存空间为作业"<<(assign->num)<<"分配"<<endl; delete assign;}}else{ //内存中如果已经分配了空间MEMORY *previous,*current;previous=ptr;//previous为链表中的第一个元素current=previous->next;while(current!=NULL){//当前区间不为空(最后一个区间的next为空),即没有循环到最后//如果当前内存空间大于作业所需空间并且内存没有被分配//则结束循环,当前current位置即为要插入的位置if(current->size>=assign->size&¤t->state==0){break;}previous=current; //previous后移current=current->next;}if(current==NULL){ //空闲链中没有为作业分配所需的空间,即释放的空闲区间小于要分配的作业空间//不够用,则在所有作业后边另外再申请空闲区,如作业4if(ptr->size>=assign->size){ //内存中还有足够没分配的空闲空间为此作业分配//此时ptr指向内存上未分配空闲空间的起始地址assign->address =640-(ptr->size);ptr->size=ptr->size-assign->size;assign->state=1;assign->former=previous;previous->next=assign;cout<<"作业 "<<(assign->num)<<"申请"<<(assign->size)<<" "<<"k的内存空间"<<endl;}else{cout<<"没有足够的内存空间为作业"<<(assign->num)<<"分配"<<endl;}}else{ //释放的空闲链中有可为此作业分配的空间if((current->size-assign->size)<=size_min){ //空闲链所具备的空间与作业所需空间大小差不多时//直接把整个空闲块的空间分配给作业否则从空闲块中current->num=assign->num; //划出与作业等同的空间current->state=1;delete assign;cout<<"作业 "<<(current->num)<<"申请"<<(current->size)<<" "<<"k 的内存间"<<endl;}else{ //从空闲块中划分一块与作业大小等同的空间current->size=current->size-assign->size;assign->state=1;assign->address=current->address+current->size;if(current->next==NULL){ //此要分配的空间是空闲链的最后一个元素assign->former=current;current->next=assign;}else{assign->next=current->next;(current->next)->former=assign;assign->former=current;current->next=assign;}cout<<"作业 "<<(assign->num)<<"申请"<<(assign->size)<<" "<<"k的内存空间"<<endl;}}}}六.调试结果1输入条件作业1申请130KB;作业2申请60KB;作业3申请100KB;作业2释放60KB;作业4申请200 KB;作业3释放100 KB;作业1释放130 KB;作业5申请140 KB;作业6申请60 KB;作业7申请50KB;作业6释放60 KB2运行结果:七.总结本次操作系统课程设计让我掌握了动态分区分配的实质:动态分区分配是根据进程的实际需要,动态地为之分配内存空间。