实验四动态分区分配算法
- 格式:doc
- 大小:75.00 KB
- 文档页数:14
实验报告四动态分区分配算法班级学号姓名一、实验目的动态分区分配是根据进程的实际需要,动态地为之分配内存空间,而在分配时,须按照一定的分配算法,从空闲分区表或空闲分区链中选出一分区分配给该作业。
在本实验中运用了四种分配算法,分别是1.首次适应算法,2.循环首次适应算法,3.最坏适应算法4.最佳适应算法。
二、实验环境普通的计算机一台,编译环境Microsoft Visual C++ 6.0三、算法思想1.数据结构(1)分区开始地址startaddress(2)分区大小size(3)分区状态state2.功能介绍(1)首次适应算法在首次适应算法中,是从已建立好的数组中顺序查找,直至找到第一个大小能满足要求的空闲分区为止,然后再按照作业大小,从该分区中划出一块内存空间分配给请求者,余下的空间令开辟一块新的地址,大小为原来的大小减去作业大小,若查找结束都不能找到一个满足要求的分区,则此次内存分配失败。
(2)循环首次适应算法该算法是由首次适应算法演变而成,在为进程分配内存空间时,不再是每次都从第一个空间开始查找,而是从上次找到的空闲分区的下一个空闲分区开始查找,直至找到第一个能满足要求的空闲分区,从中划出一块与请求大小相等的内存空间分配给作业,为实现本算法,设置一个全局变量f,来控制循环查找,当f%N==0时,f=0;若查找结束都不能找到一个满足要求的分区,则此次内存分配失败。
(3)最坏适应算法最坏适应分配算法是每次为作业分配内存时,扫描整个数组,总是把能满足条件的,又是最大的空闲分区分配给作业。
(4)最佳适应算法最坏适应分配算法是每次为作业分配内存时,扫描整个数组,总是把能满足条件的,又是最小的空闲分区分配给作业。
四、源程序#include <stdio.h>#define L 10typedef struct LNode{int startaddress;int size;int state;}LNode;LNodeP[L]={{0,128,0},{200,256,0},{500,512,0},{1 500,1600,0},{5000,150,0}};int N=5; int f=0;void print(){ int i;printf("起始地址分区状态\n");for(i=0;i<N;i++)printf("%3d %8d %4d\n",P[i].startaddress, P[i].size,P[i].state);}void First(){ int i,l=0,m;printf("\n输入请求分配分区的大小:");scanf("%d",&m);for(i=0;i<N;i++){ if(P[i].size<m)continue;else if(P[i].size==m){ P[i].state=1;l=1;break; }else{P[N].startaddress=P[i].startaddress+m;P[N].size=P[i].size-m;P[i].size=m;P[i].state=1;l=1; N++;break; } }if(l==1||i<N){ printf("地址成功分配\n\n");printf("地址分配成功后的状态:\n");print(); }elseprintf("没有可以分配的地址空间\n"); } void CirFirst(){ int l=0,m,t=0;printf("\n输入请求分配分区的大小:");scanf("%d",&m);while(f<N){ if(P[f].size<m){ f=f+1;if(f%N==0){ f=0;t=1;}continue; }if(P[f].size==m && P[f].state!=1){ P[f].state=1;l=1; f++;break; }if(P[f].size>m && P[f].state!=1){ P[N].startaddress=P[f].startaddress+m;P[N].size=P[f].size-m;P[f].size=m;P[f].state=1;l=1; N++;f++; break; } }if(l==1){ printf("地址成功分配\n\n");printf("地址分配成功后的状态:\n");print(); }elseprintf("没有可以分配的地址空间\n"); } void Worst(){int i,t=0,l=0,m;int a[L];printf("\n输入请求分配分区的大小:");scanf("%d",&m);for(i=0;i<N;i++){ a[i]=0;if(P[i].size<m)continue;else if(P[i].size==m){ P[i].state=1;l=1; break; }elsea[i]=P[i].size-m; }if(l==0){ for(i=0;i<N;i++){ if(a[i]!=0)t=i; }for(i=0;i<N;i++){ if(a[i]!=0 && a[i]>a[t])t=i; }P[N].startaddress=P[t].startaddress+m;P[N].size=P[t].size-m;P[t].size=m;P[t].state=1;l=1; N++; }if(l==1||i<N){ printf("地址成功分配\n\n");printf("地址分配成功后的状态:\n");print(); }elseprintf("没有可以分配的地址空间\n"); } void Best(){ int i,t=0,l=0,m;int a[L];printf("\n输入请求分配分区的大小:");scanf("%d",&m);for(i=0;i<N;i++){ a[i]=0;if(P[i].size<m)continue;else if(P[i].size==m){ P[i].state=1;l=1;break;}elsea[i]=P[i].size-m; }if(l==0){ for(i=0;i<N;i++){ if(a[i]!=0)t=i; }for(i=0;i<N;i++){ if(a[i]!=0 && a[i]<a[t])t=i; }P[N].startaddress=P[t].startaddress+m;P[N].size=P[t].size-m;P[t].size=m;P[t].state=1;l=1; N++; }if(l==1||i<N){ printf("地址成功分配\n\n");printf("地址分配成功后的状态:\n");print(); }elseprintf("没有可以分配的地址空间\n"); } void main(){ int k=0;printf("动态分区分配算法:");while(k!=5){printf("\n~~~~~~~~主菜单~~~~~~~~~");printf("\n1、首次适应算法\n2、循环首次适应算法");printf("\n3、最坏适应算法\n4、最佳适应算法");printf("\n5、退出\n");printf("请选择算法:");scanf("%d",&k);switch(k){ case 1:printf("\n初始状态为:\n");print();First();continue;case 2:printf("\n初始状态为:\n");print();CirFirst();continue;case 3:printf("\n初始状态为:\n"); print();Worst();continue;case 4:printf("\n初始状态为:\n");print();Best();continue;case 5:break;default:printf("选择错误,请重新选择。
南昌大学实验报告学生姓名:马江涛学号:8000612091 专业班级:计算机软件121班实验类型:□验证□综合□设计□创新实验日期:2014-05-08 实验成绩:【实验要求】1、编程实现首次适应算法和最佳适应算法的动态分区分配的分配过程和回收过程。
其中,空闲分区通过分区链来管理;在进行内存分配时,系统优先使用空闲区低端的空间。
2、假设初始状态下,可用内存空间为640K,并依次有下列请求序列:1)作业1申请130KB。
2)作业2申请60KB。
3)作业3申请100KB。
4)作业2释放60KB。
5)作业4申请200KB。
6)作业3释放100KB。
7)作业1释放130KB。
8)作业5申请140KB。
9)作业6申请60KB。
10)作业7申请50KB。
11)作业6释放60KB。
请分别用首次适应算法和最佳适应算法进行内存块的分配和回收,要求每次分配和回收后显示出空闲内存分区链的情况【可参考后文的实验提示】。
3、上机时认真的进行测试,输入不同的资源分配请求,写出实验结果;4、具体要求:(1)对你的程序关键代码处进行注释。
(2)给出实验数据,对结果进行分析,说明对相关知识点的理解。
【实验目的】了解动态分区分配方式中使用的数据结构和分配算法,并进一步加深对动态分区存储管理方式及其实现过程的理解。
【实验思路】首次适应算法(First-fit):当要分配内存空间时,就查表,在各空闲区中查找满足大小要求的可用块。
只要找到第一个足以满足要球的空闲块就停止查找,并把它分配出去;如果该空闲空间与所需空间大小一样,则从空闲表中取消该项;如果还有剩余,则余下的部分仍留在空闲表中,但应修改分区大小和分区始址。
最佳适应算法(Best-fit):当要分配内存空间时,就查找空闲表中满足要求的空闲块,并使得剩余块是最小的。
然后把它分配出去,若大小恰好合适,则直按分配;若有剩余块,则仍保留该余下的空闲分区,并修改分区大小的起始地址。
内存回收:将释放作业所在内存块的状态改为空闲状态,删除其作业名,设置为空。
实验容:存储器管理实验一、实验目的采用首次适应算法〔FF〕,最正确适应算法〔BF〕,最坏适应算法〔WF〕三种不同的算法,实现对系统空闲区的动态分区分配。
二、实验题目给予顺序搜索的动态分区算法的程序。
三、实验要求读懂给出的核心代码,进展适当的修改,编译通过后,完成实验报告。
四、核心代码#include <stdio.h>#include <stdlib.h>#include <malloc.h>//常量定义#define PROCESS_NAME_LEN 32#define MIN_SLICE 10#define DEFAULT_MEM_SIZE 1024#define DEFAULT_MEM_START 0#define MA_FF 1#define MA_BF 2#define MA_WF 3int mem_size=DEFAULT_MEM_SIZE;int ma_algorithm = MA_FF;static int pid = 0;int flag = 0;struct free_block_type{int size;int start_addr;struct free_block_type *next;};struct free_block_type *free_block;//描述已分配的存块struct allocated_block{int pid; int size;int start_addr;char process_name[PROCESS_NAME_LEN];struct allocated_block *next;};struct allocated_block *allocated_block_head = NULL;//函数声明struct free_block_type* init_free_block(int mem_size);void display_menu();int set_mem_size();void set_algorithm();void rearrange(int algorithm);int rearrange_FF();int rearrange_BF();int rearrange_WF();int new_process();int allocate_mem(struct allocated_block *ab);void kill_process();int free_mem(struct allocated_block *ab);int dispose(struct allocated_block *free_ab);int display_mem_usage();void do_exit();struct allocated_block *find_process(int pid);int main(){char choice; pid=0;free_block= init_free_block(mem_size); //初始化空闲区while(1) {display_menu(); //显示菜单fflush(stdin);choice=getchar(); //获取用户输入switch(choice){case '1': set_mem_size(); break; //设置存大小case '2': set_algorithm();flag=1; break;//设置算法case '3': new_process(); flag=1; break;//创立新进程case '4': kill_process(); flag=1; break;//删除进程case '5': display_mem_usage(); flag=1; break; //显示存使用case '0': do_exit(); exit(0); //释放链表并退出default: break;}}return 1;}struct free_block_type* init_free_block(int mem_size){struct free_block_type *fb;fb=(struct free_block_type *)malloc(sizeof(struct free_block_type));if(fb==NULL){printf("No mem\n");return NULL;}fb->size = mem_size;fb->start_addr = DEFAULT_MEM_START;fb->next = NULL;return fb;}void display_menu(){printf("\n");printf("1 - Set memory size (default=%d)\n", DEFAULT_MEM_SIZE);printf("2 - Select memory allocation algorithm\n");printf("3 - New process \n");printf("4 - T erminate a process \n");printf("5 - Display memory usage \n");printf("0 - Exit\n");}int set_mem_size(){int size;if(flag!=0){ //防止重复设置printf("Cannot set memory size again\n");return 0;}printf("T otal memory size =");scanf("%d", &size);if(size>0) {mem_size = size;free_block->size = mem_size;}flag=1;return 1;}void set_algorithm(){int algorithm;while(1) {printf("\t1 - First Fit\n");printf("\t2 - Best Fit \n");printf("\t3 - Worst Fit \n");scanf("%d", &algorithm);if(algorithm>=1 && algorithm <=3) {ma_algorithm = algorithm;break;}elseprintf("输入有误,请重新输入!\n");}//按指定算法重新排列空闲区链表rearrange(ma_algorithm);}void rearrange(int algorithm){switch(algorithm){case MA_FF: rearrange_FF(); break;case MA_BF: rearrange_BF(); break;case MA_WF: rearrange_WF(); break;}}//首次适应算法int rearrange_FF(){struct free_block_type *temp;//使用头插法,thead为临时头,p为最小地址的数据块的前一个结点struct free_block_type *thead=NULL,*p=NULL;//当前的最小地址int min_addr = free_block->start_addr;temp = free_block;while(temp->next!=NULL) {if(temp->next->start_addr<min_addr) {min_addr = temp->next->start_addr;p = temp;}temp = temp->next;}if(NULL!=p) {temp = p->next;p->next = p->next->next;temp->next = free_block;free_block = temp;}thead = free_block;p = free_block;temp = free_block->next;while(thead->next!=NULL) {min_addr = thead->next->start_addr;while(temp->next!=NULL) {if(temp->next->start_addr<min_addr) {min_addr = temp->next->start_addr;p = temp;}temp = temp->next;}if(p->next!=thead->next) {temp = p->next;p->next = p->next->next;temp->next = thead->next;thead->next = temp;}thead = thead->next;p = thead;temp = thead->next;}return 1;}//最正确适应算法int rearrange_BF(){struct free_block_type *temp;//使用头插法,thead为临时头,p为最小存的数据块的前一个结点struct free_block_type *thead=NULL,*p=NULL;//当前的最小存int min_size = free_block->size;temp = free_block;while(temp->next!=NULL) {if(temp->next->size<min_size) {min_size = temp->next->size;p = temp;}temp = temp->next;}if(NULL!=p) {temp = p->next;p->next = p->next->next;temp->next = free_block;free_block = temp;}thead = free_block;p = free_block;temp = free_block->next;while(thead->next!=NULL) {min_size = thead->next->size;while(temp->next!=NULL) {if(temp->next->size<min_size) {min_size = temp->next->size;p = temp;}temp = temp->next;}if(p->next!=thead->next) {temp = p->next;p->next = p->next->next;temp->next = thead->next;thead->next = temp;}thead = thead->next;p = thead;temp = thead->next;}return 1;}//最坏适应算法int rearrange_WF(){struct free_block_type *temp;//使用头插法,thead为临时头,p为最大存的数据块的前一个结点struct free_block_type *thead=NULL,*p=NULL;//当前的最大存int max_size = free_block->size;temp = free_block;while(temp->next!=NULL) {if(temp->next->size>max_size) {max_size = temp->next->size;p = temp;}temp = temp->next;}if(NULL!=p) {temp = p->next;p->next = p->next->next;temp->next = free_block;free_block = temp;}thead = free_block;p = free_block;temp = free_block->next;while(thead->next!=NULL) {max_size = thead->next->size;while(temp->next!=NULL) {if(temp->next->size>max_size) {max_size = temp->next->size;p = temp;}temp = temp->next;}if(p->next!=thead->next) {temp = p->next;p->next = p->next->next;temp->next = thead->next;thead->next = temp;}thead = thead->next;p = thead;temp = thead->next;}return 1;}int new_process(){struct allocated_block *ab;int size;int ret;ab = (struct allocated_block *)malloc(sizeof(struct allocated_block));if(!ab) exit(-5);ab->next = NULL;pid++;sprintf(ab->process_name, "PROCESS-d", pid);ab->pid = pid;while(1) {printf("Memory for %s:", ab->process_name);scanf("%d", &size);if(size>0) {ab->size=size;break;}else printf("输入大小有误,请重新输入\n");}ret = allocate_mem(ab);if((ret==1) &&(allocated_block_head == NULL)){allocated_block_head=ab;return 1;}else if (ret==1) {ab->next = allocated_block_head;allocated_block_head = ab;return 2; }else if(ret==-1){printf("Allocation fail\n");pid--;free(ab);return -1;}return 3;}int allocate_mem(struct allocated_block *ab){struct free_block_type *fbt, *pre,*head,*temp,*tt;struct allocated_block *tp;int request_size=ab->size;int sum=0;int max;head = (struct free_block_type *)malloc(sizeof(struct free_block_type));pre = head;fbt = free_block;pre->next = fbt;if(ma_algorithm==MA_WF) {if(NULL==fbt||fbt->size<request_size)return -1;}else {while(NULL!=fbt&&fbt->size<request_size) {pre = fbt;fbt = fbt->next;}}if(NULL==fbt||fbt->size<request_size) {if(NULL!=free_block->next) {sum = free_block->size;temp = free_block->next;while(NULL!=temp) {sum += temp->size;if(sum>=request_size)break;temp = temp->next;}if(NULL==temp)return -1;else {pre = free_block;max = free_block->start_addr;fbt = free_block;while(temp->next!=pre) {if(max<pre->start_addr) {max = pre->start_addr;fbt = pre;}pre = pre->next;}pre = free_block;while(temp->next!=pre) {tp = allocated_block_head;tt = free_block;if(pre!=fbt) {while(NULL!=tp) {if(tp->start_addr>pre->start_addr)tp->start_addr = tp->start_addr - pre->size;tp = tp->next;}while(NULL!=tt) {if(tt->start_addr>pre->start_addr)tt->start_addr = tt->start_addr - pre->size;tt = tt->next;}}pre = pre->next;}pre = free_block;while(pre!=temp->next) {if(pre!=fbt)free(pre);pre = pre->next;}free_block = fbt;free_block->size = sum;free_block->next = temp->next;if(free_block->size - request_size < MIN_SLICE) {ab->size = free_block->size;ab->start_addr = free_block->start_addr;pre = free_block;free_block = free_block->next;free(pre);}else {ab->start_addr = fbt->start_addr;free_block->start_addr = free_block->start_addr + request_size;free_block->size = free_block->size - request_size;}}}elsereturn -1;}else {//将存块全局部配if(fbt->size - request_size < MIN_SLICE) {ab->size = fbt->size;ab->start_addr = fbt->start_addr;if(pre->next==free_block) {free_block = fbt->next;}elsepre->next = fbt->next;free(fbt);}else {ab->start_addr = fbt->start_addr;fbt->start_addr = fbt->start_addr + request_size;fbt->size = fbt->size - request_size;}}free(head);rearrange(ma_algorithm);return 1;}void kill_process(){struct allocated_block *ab;int pid;printf("Kill Process, pid=");scanf("%d", &pid);ab = find_process(pid);if(ab!=NULL){free_mem(ab);dispose(ab);}else {printf("没有pid为%d的进程!\n",pid);}}struct allocated_block *find_process(int pid) {struct allocated_block *ab=NULL;ab = allocated_block_head;while(NULL!=ab&&ab->pid!=pid)ab = ab->next;return ab;}int free_mem(struct allocated_block *ab){int algorithm = ma_algorithm;struct free_block_type *fbt, *pre=NULL,*head;fbt=(struct free_block_type*) malloc(sizeof(struct free_block_type));pre=(struct free_block_type*) malloc(sizeof(struct free_block_type));if(!fbt) return -1;// 进展可能的合并,根本策略如下// 1. 将新释放的结点插入到空闲分区队列末尾// 2. 对空闲链表按照地址有序排列// 3. 检查并合并相邻的空闲分区// 4. 将空闲链表重新按照当前算法排序head = pre;fbt->start_addr = ab->start_addr;fbt->size = ab->size;fbt->next = free_block; //新释放的结点插入到空闲分区链表的表头free_block = fbt;rearrange_FF(); //对空闲链表按照地址有序排列pre->next = free_block; //求的pre为fbt的前一个结点pre->size = 0;while(pre->next->start_addr!=fbt->start_addr)pre = pre->next;//左右分区都存在if(0!=pre->size&&NULL!=fbt->next) {//左右分区都可合并if((pre->start_addr+pre->size)==fbt->start_addr && (fbt->start_addr+fbt->size)==fbt->next->start_addr) {pre->size = pre->size + fbt->size + fbt->next->size;pre->next = fbt->next->next;free(fbt->next);free(fbt);}//左分区可合并else if((pre->start_addr+pre->size)==fbt->start_addr) {pre->size = pre->size + fbt->size;pre->next = fbt->next;free(fbt);}//右分区可合并else if((fbt->start_addr+fbt->size)==fbt->next->start_addr) {fbt->size = fbt->size + fbt->next->size;fbt->next = fbt->next->next;free(fbt->next);}}//左分区不存在else if(0==pre->size) {if((fbt->start_addr+fbt->size)==fbt->next->start_addr) {fbt->size = fbt->size + fbt->next->size;fbt->next = fbt->next->next;free(fbt->next);}}//右分区不存在else if(NULL==fbt->next) {if((pre->start_addr+pre->size)==fbt->start_addr) {pre->size = pre->size + fbt->size;pre->next = fbt->next;free(fbt);}}rearrange(algorithm);free(head);return 1;}int dispose(struct allocated_block *free_ab){struct allocated_block *pre, *ab;if(free_ab == allocated_block_head) {allocated_block_head = allocated_block_head->next;free(free_ab);return 1;}pre = allocated_block_head;ab = allocated_block_head->next;while(ab!=free_ab){ pre = ab; ab = ab->next; }pre->next = ab->next;free(ab);return 2;}int display_mem_usage(){struct free_block_type *fbt=free_block;struct allocated_block *ab=allocated_block_head;if(fbt==NULL) return(-1);printf("----------------------------------------------------------\n");printf("Free Memory:\n");printf(" s s\n", " start_addr", " size");while(fbt!=NULL){printf(" d d\n", fbt->start_addr, fbt->size);fbt=fbt->next;}printf("\nUsed Memory:\n");printf("s s s s\n", "PID", "ProcessName", "start_addr", " size");while(ab!=NULL){printf("d s d d\n", ab->pid, ab->process_name, ab->start_addr, ab->size);ab=ab->next;}printf("----------------------------------------------------------\n");return 0;}void do_exit() {}。
实验四内存分配算法1.实验目的一个好的计算机系统不仅要有一个足够容量的、存取速度高的、稳定可靠的主存储器,而且要能合理地分配和使用这些存储空间。
当用户提出申请主存储器空间时,存储管理必须根据申请者的要求,按一定的策略分析主存空间的使用情况,找出足够的空闲区域分配给申请者。
当作业撤离或主动归还主存资源时,则存储管理要收回作业占用的主存空间或归还部分主存空间。
主存的分配和回收的实现是与主存储器的管理方式有关的,通过本实验帮助学生理解在动态分区管理方式下应怎样实现主存空间的分配和回收。
背景知识:可变分区方式是按作业需要的主存空间大小来分割分区的。
当要装入一个作业时,根据作业需要的主存量查看是否有足够的空闲空间,若有,则按需要量分割一个分区分配给该作业;若无,则作业不能装入。
随着作业的装入、撤离、主存空间被分成许多个分区,有的分区被作业占用,而有的分区是空闲的。
2.实验内容采用首次适应算法或循环首次算法或最佳适应算法分配主存空间。
由于本实验是模拟主存的分配,所以当把主存区分配给作业后并不实际启动装入程序装入作业,而用输出“分配情况”来代替。
(即输出当时的空闲区说明表及其内存分配表)利用VC++6.0实现上述程序设计和调试操作。
3.实验代码#include<iostream>#include<list>using namespace std;//定义内存的大小const int SIZE=64;//作业结构体,保存作业信息struct Project{int number;int length;};//内存块结构体,保存内存块信息struct Block{int address;int length;int busy;};int first_fit(list<Block> &, Project , list<Project> &);//声明首次适配算法函数int best_fit(list<Block> &, Project , list<Project> &);//声明最佳适配算法函数int next_fit(list<Block> &, Project , list<Project> &);//声明下次适配算法函数void swap_out(list<Block> &, Project , list<Project> &);//声明换出作业的函数void print_info(list<Block>, list<Project>);//声明打印内存和作业函数int remain_length(list<Block>);//声明计算剩余内存的函数int main(){list<Block> B_List;list<Project> P_List;Block m1 = { 1, SIZE, 0 };B_List.push_back(m1);print_info(B_List, P_List);while (true){cout << "\n\t\t1.装入作业" << endl << "\t\t2.换出作业" << endl << "\t\t3.退出\n" << endl << "请选择操作:";int choice;cin >> choice;switch (choice){case 1://装入作业{cout << "请选择装入方式:(1.首次适配 2.最佳适配 3.下次适配):\n";int c1;cin >> c1;cout << "请输入作业号(作业号不能重复):";int c2;cin >> c2;cout << "请输入作业所需内存:";int c3;cin >> c3;Project p = { c2, c3 };if (c1 == 1){first_fit(B_List, p, P_List);}else if (c1 == 2){best_fit(B_List, p, P_List);}else if (c1 == 3){next_fit(B_List, p, P_List);}print_info(B_List, P_List);break;}case 2://换出作业{cout << "请选择需换出内存的作业:";int c3;cin >> c3;Project p = { c3, 5 };swap_out(B_List, p, P_List);print_info(B_List, P_List);break;}default://退出{return 0;}}}}//首次适配int first_fit(list<Block> &L1, Project p, list<Project> &L2){ list<Block>::iterator i;//遍历列表查找空闲分区for (i = L1.begin(); i != L1.end(); i++){//空闲分区大小和作业相同if (p.length == i->length && i->busy == 0){i->busy = p.number;L2.push_back(p);return 1;}//空闲分区比作业内存大if (p.length < i->length && i->busy == 0){i->busy = p.number;int len= i->length-p.length;i->length = p.length;Block m = { i->address + p.length, len, 0 };L1.insert(++i, m);i--;L2.push_back(p);return 1;}}cout << "内存不足,作业" << p.number << "装入失败" << endl;return 0;}//最佳适配int best_fit(list<Block> &L1, Project p, list<Project> &L2){list<Block>::iterator i, j;int min = 100000;for (i = L1.begin(); i != L1.end(); i++){if (i->length - p.length>-1 && i->length - p.length<min && i->busy == 0){ j = i;//找到大于或等于作业内存的最小空闲内存min = i->length - p.length;}}i = j;//空闲分区大小和作业相同if (min == 0){i->busy = p.number;L2.push_back(p);return 1;}//空闲分区比作业内存大else if (min != 100000){i->busy = p.number;int len = i->length-p.length;i->length = p.length;Block m = { i->address + p.length, len, 0 };L1.insert(++i, m);i--;L2.push_back(p);return 1;}if (i == --L1.end()){cout << "内存不足,作业" << p.number << "装入失败" << endl;return 0;}}//下次适配int next_fit(list<Block> &L1, Project p, list<Project> &L2){ int pnumber = L2.back().number;list<Block>::iterator i;//找到前一次装入的作业位置for (i = L1.begin(); i != L1.end(); i++){if (i->busy == pnumber){break;}}for (; i != L1.end(); i++){//空闲分区大小和作业相同if (p.length == i->length && i->busy == 0){i->busy = p.number;L2.push_back(p);return 1;}//空闲分区比作业内存大if (p.length < i->length && i->busy == 0){i->busy = p.number;int len = i->length-p.length;i->length = p.length;Block m = { i->address + p.length, len, 0 };L1.insert(++i, m);i--;L2.push_back(p);return 1;}if (i == --L1.end()){cout << "内存不足,作业" << p.number << "装入失败" << endl;return 0;}}return 0;}//换出作业void swap_out(list<Block> &L1, Project p, list<Project> &L2){ int pnumber = p.number;list<Project>::iterator i2;for (i2 = L2.begin(); i2 != L2.end(); i2++){//根据作业号换出作业if ((*i2).number == pnumber){L2.erase(i2);break;}}list<Block>::iterator i,j,k;for (i = L1.begin(); i != L1.end(); i++){if (i->busy == pnumber){i->busy = 0;j = i;k = i;if (j != L1.begin()){j--;//换出作业后前一个空闲区正好能连接if (j->busy == 0){i->length += j->length;i->address = j->address;L1.erase(j);}}k++;//换出作业后后一个空闲区正好能连接if (k->busy == 0){i->length += ((*k).length);L1.erase(k);}break;}}}//计算剩余内存int remain_length(list<Block>L1){list<Block>::iterator i;//当前所有作业占用的总内存int len=0;for (i = L1.begin(); i != L1.end(); i++){if (i->busy != 0)len += i->length;}return SIZE-len;}void print_info(list<Block> L1, list<Project> L2){cout << "\n***********************************************" << endl;cout << "总内存:"<<SIZE <<"\t剩余内存:"<<remain_length(L1)<<endl;list<Block>::iterator i;for (i = L1.begin(); i != L1.end(); i++){if (i->busy == 0){cout << " 首地址: " << i->address << " 长度: " << i->length << " 空闲" << endl;}elsecout << " 首地址: " << i->address << " 长度: " << i->length << " 被作业" << i->busy << "占用" << endl;}cout << "***********************************************" << endl;cout << "作业明细(按进入顺序排):" << endl;list<Project>::iterator j;for (j = L2.begin(); j!= L2.end(); j++){cout << " 作业号:" << j->number << " 长度: " << j->length << endl;}cout << "***********************************************" << endl;}4.运行截图1.初始时内存情况:2.采用首次适配算法依次放入作业1(10),作业2(5)作业3(20)作业4(15)后的内存情况:3.换出作业2后内存情况:4.采用最佳适配算法放入作业5(3)后的内存情况:5.换出作业3采用最佳适配算法放入作业6(13)内存情况:6.采用下次适配算法装入作业7(1)内存情况:5.实验中遇到的问题和解决方法实验的难点在于数据结构的选择和内存分配算法的模拟。
实验四动态分区存储管理实验目的:熟悉并掌握动态分区分配的各种算法。
熟悉并掌握动态分区中分区回收的各种情况,并能够实现分区合并。
实验内容:用高级语言模拟实现动态分区存储管理,要求:1、分区分配算法至少实现首次适应算法、最佳适应算法和最坏适应算法中的至少一种。
熟悉并掌握各种算法的空闲区组织方式。
2、分区的初始化——可以由用户输入初始分区的大小。
(初始化后只有一个空闲分区,起始地址为0,大小是用户输入的大小)3、分区的动态分配过程:由用户输入作业号和作业的大小,实现分区过程。
4、分区的回收:用户输入作业号,实现分区回收,同时,分区的合并要体现出来。
(注意:不存在的作业号要给出错误提示!)5、分区的显示:任何时刻,可以查看当前内存的情况(起始地址是什么,大小多大的分区时空闲的,或者占用的,能够显示出来)6、要求考虑:(1)内存空间不足的情况,要有相应的显示;(2)作业不能同名,但是删除后可以再用这个名字;(3)作业空间回收是输入作业名,回收相应的空间,如果这个作业名不存在,也要有相应的提示。
#include "iostream.h"#include "iomanip.h"#define ERR_NOFREEAREA 1#define ERR_NOADEQUACYAREA 2#define ERR_ALLOCATED 4#define ERR_NOJOBS 1#define ERR_NOSUCHJOB 2#define ERR_RECLAIMED 4typedef struct tagUsedNode{long address;long length;int flag;//作业名struct tagUsedNode *next;}USED_AREA, *USED_TABLE;typedef struct tagFreeNode{long address;long length;struct tagFreeNode *next;}FREE_AREA, *FREE_TABLE;//空闲区、作业区链表USED_TABLE usedTable=NULL;FREE_TABLE freeTable=NULL;//给作业分配空间int Allocate(int jobname,long jobsize){//如果没有空闲区if(freeTable==NULL)return ERR_NOFREEAREA;FREE_TABLE p=freeTable;FREE_TABLE q=p;//找首次适应空闲区while(p!=NULL&&p->length<jobsize){q=p;p=p->next;}//如果找不到有足够空间的分区if(p==NULL)return ERR_NOADEQUACYAREA;USED_TABLE x=new USED_AREA;x->address=p->address;x->length=jobsize;x->flag=jobname;x->next=NULL;//如果该分区大于作业需求,空间大小减去作业大小if(p->length>jobsize){p->length-=jobsize;p->address+=jobsize;}//如果该分区等于作业大小,删除该分区else{if( p==freeTable)freeTable=NULL;elseq->next=p->next;delete p;}//作业加入"作业表"中USED_TABLE r=usedTable;USED_TABLE t=r;while(r!=NULL&&r->address<x->address) {t=r;r=r->next;}if(usedTable==NULL)usedTable=x;else{x->next=r;t->next=x;}return ERR_ALLOCATED;}//回收作业空间int Reclaim(int jobname){if(usedTable==NULL)return ERR_NOJOBS;USED_TABLE p=usedTable;USED_TABLE q=p;while(p!=NULL&&p->flag!=jobname) {q=p;p=p->next;}//如果没有该作业if(p==NULL)return ERR_NOSUCHJOB;//回收后的空间加入到空闲区FREE_TABLE r=freeTable;FREE_TABLE t=r;FREE_TABLE x;while(r!=NULL&&r->address<p->address) {t=r;r=r->next;}x=new FREE_AREA;x->address=p->address;x->length=p->length;x->next=NULL;if(r==freeTable ){x->next=r;freeTable=x;t=freeTable;}else{x->next=r;t->next=x;}//合并分区while(t->next!=NULL&&t->address+t->length==t->next->address) {t->length+=t->next->length;r=t->next;t->next=t->next->next;delete r;}//删除作业if( p==usedTable){usedTable=usedTable->next;}elseq->next=p->next;delete p;return ERR_RECLAIMED;}int Init(){freeTable=new FREE_AREA;freeTable->address=0;freeTable->length=1024;freeTable->next=NULL;return 1;}void jobrequest(){int jobname;int jobsize;cout<<"\n************************"<<endl;cout<<"作业名: ";cin>>jobname;cout<<"作业长度: ";cin>>jobsize;if(Allocate(jobname,jobsize)==ERR_ALLOCATED)cout<<"该作业已成功获得所需空间"<<endl;elsecout<<"该作业没有获得所需空间"<<endl;cout<<"************************\n"<<endl;}void jobreclaim(){int jobname;cout<<"\n************************"<<endl;cout<<"作业名: ";cin >>jobname;int result=Reclaim(jobname);if(result==ERR_RECLAIMED)cout<<"该作业已成功回收"<<endl;else if(result==ERR_NOSUCHJOB||result==ERR_NOJOBS)cout<<"该作业不存在,请重新输入"<<endl;cout<<"************************\n"<<endl;}void freeTablePrint(){cout<<"\n*****************************************"<<endl;cout<<setw(10)<<"地址"<<setw(10)<<"大小"<<setw(10)<<"状态"<<endl<<endl;FREE_TABLE p=freeTable;USED_TABLE q=usedTable;int x,y;while(p||q){if(p)x=p->address;elsex=0x7fffffff;if(q)y=q->address;elsey=0x7fffffff;if(x<y){cout<<setw(10)<<p->address<<setw(10)<<p->length<<setw(10)<<"空闲"<<endl;p=p->next;}if(x>y){cout<<setw(10)<<q->address<<setw(10)<<q->length<<setw(10)<<"已分配"<<setw(10)<<"ID="<<q->flag<<endl;q = q->next;}}cout<<"*****************************************\n"<<endl;}void main(){Init();int choose;bool exitFlag = false;while(!exitFlag){cout<<"-----------------------输入选择项-----------------------"<<endl;cout<<"------ 1 分配分区 2 回收分区 3 显示分区 4 退出------"<<endl;cout<<"--------------------------------------------------------\n"<<endl;cout<<"选择: ";cin>>choose;switch(choose){break;case 1:jobrequest();break;case 2:jobreclaim();break;case 3:freeTablePrint();break;case 4:exitFlag=true;}}}。
动态分区算法实验报告动态分区算法实验报告一、引言计算机操作系统是现代计算机系统中的核心组成部分,它负责管理计算机硬件资源,并提供各种服务。
内存管理是操作系统的重要功能之一,它负责管理计算机的内存资源,为进程提供运行环境。
在内存管理中,动态分区算法是一种常用的内存分配策略。
本实验旨在通过实践,深入了解动态分区算法的原理和实现。
二、实验目的1. 了解动态分区算法的基本原理和实现方式;2. 掌握动态分区算法的实验环境搭建和使用方法;3. 分析动态分区算法的优缺点,并比较不同算法的性能差异。
三、实验环境本实验使用C语言编程实现,实验环境如下:1. 操作系统:Windows 10;2. 开发工具:Visual Studio 2019;3. 编程语言:C语言。
四、实验过程1. 实验准备在开始实验之前,我们首先需要了解动态分区算法的基本原理。
动态分区算法根据进程的内存需求,将内存划分为若干个不同大小的分区,并按照进程的请求进行分配和释放。
常用的动态分区算法有首次适应算法、最佳适应算法和最坏适应算法等。
2. 实验设计本实验选择实现首次适应算法,并设计以下几个函数:- 初始化内存空间:初始化一块指定大小的内存空间,将其划分为一个个的分区,并设置分区的状态;- 分配内存:根据进程的内存需求,在内存空间中找到合适的分区进行分配,并更新分区的状态;- 释放内存:将已分配的内存空间进行释放,并更新分区的状态;- 显示内存状态:打印当前内存空间的分区状态。
3. 实验实现根据上述设计,我们使用C语言实现了动态分区算法的相关函数。
通过调用这些函数,我们可以模拟动态分区算法的运行过程,并观察分区的分配和释放情况。
4. 实验结果经过实验,我们得到了以下结果:- 动态分区算法可以有效地管理内存资源,根据进程的需求进行灵活的内存分配;- 首次适应算法在内存分配效率和速度方面表现良好,但可能会导致内存碎片的产生;- 释放内存时,及时合并相邻的空闲分区可以减少内存碎片的数量。
实验题目:存储器内存分配设计思路:1.既然是要对内存进行操作,首先对和内存相关的内容进行设置我使用的是用自定义的数据结构struct来存放内存中一个内存块的内容包括:始地址、大小、状态(f:空闲u:使用e:结束)之后采用数组来存放自定义的数据类型,这样前期的准备工作就完成了2.有了要加工的数据,接下来定义并实现了存放自定义数据类型的数组的初始化函数和显示函数,需要显示的是每个内存块的块号、始地址、大小、状态3.接着依此定义三种动态分区分配算法首次适应算法、最佳适应算法和最差适应算法4.对定义的三种算法逐一进行实现①首次适应算法:通过遍历存放自定义数据类型的数组,找到遍历过程中第一个满足分配大小的内存块块号i,找到之后停止对数组的遍历,将i之后的块号逐个向后移动一个,然后将满足分配大小的内存块i分为两块,分别是第i块和第i+1块,将两块的始地址、大小、状态分别更新,这样便实现了首次适应算法②最佳适应算法:和首次适应算法一样,首先遍历存放自定义数据类型的数组,找到满足分配大小的内存块后,对内存块的大小进行缓存,因为最佳适应是要找到最接近要分配内存块大小的块,所以需要遍历整个数组,进而找到满足分配大小要求的而且碎片最小的块i,之后的操作和首次遍历算法相同③最差适应算法:和最佳适应算法一样,区别在于,最佳适应是找到最接近要分配内存块大小的块,而最差适应是要找到在数组中,内存最大的块i,找到之后的操作和最佳适应算法相同,因此不在这里赘述。
5.定义并实现释放内存的函数通过块号找到要释放的内存块,把要释放的内存块状态设置成为空闲,查看要释放的块的左右两侧块的状态是否为空闲,如果有空闲,则将空闲的块和要释放的块进行合并(通过改变块的始地址、大小、状态的方式)6.定义主函数,用switch来区分用户需要的操作,分别是:①首次适应②最佳适应③最差适应④释放内存⑤显示内存⑥退出系统实验源程序加注释:#include<bits/stdc++.h>#define MI_SIZE 100 //内存大小100typedef struct MemoryInfomation//一个内存块{int start; //始地址int Size; //大小char status; //状态 f:空闲 u:使用 e:结束} MI;MI MList[MI_SIZE];void InitMList() //初始化{int i;MI temp = { 0,0,'e' };for (i = 0; i < MI_SIZE; i++){MList[i] = temp;}MList[0].start = 0; //起始为0MList[0].Size = MI_SIZE;//大小起始最大MList[0].status = 'f'; //状态起始空闲}void Display() //显示{int i, used = 0;printf("\n---------------------------------------------------\n");printf("%5s%15s%15s%15s", "块号", "始地址", "大小", "状态");printf("\n---------------------------------------------------\n");for (i = 0; i < MI_SIZE && MList[i].status != 'e'; i++){if (MList[i].status == 'u'){used += MList[i].Size;}printf("%5d%15d%15d%15s\n", i, MList[i].start, MList[i].Size, MList[i].status == 'u' ? "使用" : "空闲");}printf("\n----------------------------------------------\n");}void FirstFit(){int i, j, flag = 0;int request;printf("最先适应算法:请问你要分配多大的内存\n");scanf("%d", &request);for (i = 0; i < MI_SIZE && MList[i].status != 'e'; i++){if (MList[i].Size >= request && MList[i].status == 'f') {if (MList[i].Size - request <= 0){MList[i].status = 'u';}else{for (j = MI_SIZE - 2; j > i; j--){MList[j + 1] = MList[j];}MList[i + 1].start = MList[i].start + request; MList[i + 1].Size = MList[i].Size - request;MList[i + 1].status = 'f';MList[i].Size = request;MList[i].status = 'u';flag = 1;}break;}}if (flag != 1 || i == MI_SIZE || MList[i].status == 'e'){printf("没有足够大小的空间分配\n");}Display();}void BadFit(){int i, j = 0, k = 0, flag = 0, request;printf("最坏适应算法:请问你要分配多大的内存\n");scanf("%d", &request);for (i = 0;i < MI_SIZE - 1 && MList[i].status != 'e';i++){if (MList[i].Size >= request && MList[i].status == 'f') {flag = 1;if (MList[i].Size > k){k = MList[i].Size;j = i;}}}i = j;if (flag == 0){printf("没有足够大小的空间分配\n");j = i;}else if (MList[i].Size - request <= 0){MList[i].status = 'u';}else{for (j = MI_SIZE - 2;j > i;j--){MList[j + 1] = MList[j];}MList[i + 1].start = MList[i].start + request;MList[i + 1].Size = MList[i].Size - request;MList[i + 1].status = 'f';MList[i].Size = request;MList[i].status = 'u';}Display();}void M_Release() //释放内存{int i, number;printf("\n请问你要释放哪一块内存:\n");scanf("%d", &number);if (MList[number].status == 'u'){MList[number].status = 'f';if (MList[number + 1].status == 'f')//右边空则合并{MList[number].Size += MList[number].Size;for (i = number + 1; i < MI_SIZE - 1 && MList[i].status != 'e'; i++) { //i后面的每一个结点整体后移if (i > 0){MList[i] = MList[i + 1];}}}if (number > 0 && MList[number - 1].status == 'f')//左边空则合并{MList[number - 1].Size += MList[number].Size;for (i = number; i < MI_SIZE - 1 && MList[i].status != 'e'; i++){MList[i] = MList[i + 1];}}}else{printf("该块内存无法正常释放\n");}Display();}void BestFit(){int i, j = 0, t, flag = 0, request;printf("最佳适应算法:请问你要分配多大的内存\n");scanf("%d", &request);t = MI_SIZE;for (i = 0; i < MI_SIZE && MList[i].status != 'e'; i++){if (MList[i].Size >= request && MList[i].status == 'f'){flag = 1;if (MList[i].Size < t){t = MList[i].Size;j = i;}}}i = j;if (flag == 0){printf("没有足够大小的空间分配\n");j = i;}else if (MList[i].Size - request <= 0){MList[i].status = 'u';}else {for (j = MI_SIZE - 2; j > i; j--){MList[j + 1] = MList[j];}MList[i + 1].start = MList[i].start + request;MList[i + 1].Size = MList[i].Size - request;MList[i + 1].status = 'f';MList[i].Size = request;MList[i].status = 'u';}Display();}int main(){int x;InitMList();while (1){printf(" \n"); printf(" 1.首次适应\n");printf(" 2.最佳适应\n");printf(" 3.最差适应\n"); printf(" 4.释放内存\n"); printf(" 5.显示内存\n"); printf(" 6.退出系统\n"); printf("请输入1-6:");scanf("%d", &x);switch (x){case 1:FirstFit();break;case 2:BestFit();break;case 3:BadFit();break;case 4:M_Release();break;case 5:Display();break;case 6:exit(0);}}return 0;}实验测试结果记录:1.首次适应2.最佳适应3.最差适应4.释放内存5.显示内存6.退出系统请输入1-6:1最先适应算法:请问你要分配多大的内存10---------------------------------------------------块号始地址大小状态---------------------------------------------------0 0 10 使用1 10 90 空闲----------------------------------------------1.首次适应2.最佳适应3.最差适应4.释放内存5.显示内存6.退出系统请输入1-6:1最先适应算法:请问你要分配多大的内存25---------------------------------------------------块号始地址大小状态---------------------------------------------------0 0 10 使用1 10 25 使用2 35 65 空闲----------------------------------------------1.首次适应2.最佳适应3.最差适应4.释放内存5.显示内存6.退出系统请输入1-6:1最先适应算法:请问你要分配多大的内存15---------------------------------------------------块号始地址大小状态---------------------------------------------------0 0 10 使用1 10 25 使用2 35 15 使用3 50 50 空闲----------------------------------------------1.首次适应2.最佳适应3.最差适应4.释放内存5.显示内存6.退出系统请输入1-6:1最先适应算法:请问你要分配多大的内存20---------------------------------------------------块号始地址大小状态---------------------------------------------------0 0 10 使用1 10 25 使用2 35 15 使用3 50 20 使用4 70 30 空闲----------------------------------------------1.首次适应2.最佳适应3.最差适应4.释放内存5.显示内存6.退出系统请输入1-6:4请问你要释放哪一块内存:---------------------------------------------------块号始地址大小状态---------------------------------------------------0 0 10 空闲1 10 25 使用2 35 15 使用3 50 20 使用4 70 30 空闲----------------------------------------------1.首次适应2.最佳适应3.最差适应4.释放内存5.显示内存6.退出系统请输入1-6:4请问你要释放哪一块内存:2---------------------------------------------------块号始地址大小状态---------------------------------------------------0 0 10 空闲1 10 25 使用2 35 15 空闲3 50 20 使用4 70 30 空闲----------------------------------------------1.首次适应2.最佳适应3.最差适应4.释放内存5.显示内存6.退出系统请输入1-6:2最佳适应算法:请问你要分配多大的内存5---------------------------------------------------块号始地址大小状态---------------------------------------------------0 0 5 使用1 5 5 空闲2 10 25 使用3 35 15 空闲4 50 20 使用5 70 30 空闲----------------------------------------------1.首次适应2.最佳适应3.最差适应4.释放内存5.显示内存6.退出系统请输入1-6:3最坏适应算法:请问你要分配多大的内存25---------------------------------------------------块号始地址大小状态---------------------------------------------------0 0 5 使用1 5 5 空闲2 10 25 使用3 35 15 空闲4 50 20 使用5 70 25 使用6 95 5 空闲----------------------------------------------1.首次适应2.最佳适应3.最差适应4.释放内存5.显示内存6.退出系统请输入1-6:总结与自评:总结:分区存储管理是操作系统进行内存管理的一种方式。
动态分区分配操作系统操作方法实验步骤1.引言1.1 概述概述部分:在计算机系统中,动态分区分配是一种重要的操作系统操作方法。
它是指在运行时根据进程的内存需求动态地将系统内存分配给进程,以实现内存资源的高效利用。
动态分区分配操作方法在现代操作系统中被广泛应用,例如Windows、Linux等。
通过合理的动态分区分配策略,可以提升系统的性能和资源利用率。
本文将对动态分区分配操作系统操作方法进行详细介绍和实验步骤的说明。
首先,我们将介绍动态分区分配的背景和意义,包括其在操作系统中的作用和应用场景。
其次,我们将详细讨论实验的具体步骤,包括如何进行动态分区分配操作、如何测试相关的性能指标等。
本文的目标是帮助读者了解动态分区分配操作系统操作方法的基本原理和实践技巧。
同时,通过实际操作和实验验证,读者将能够更好地理解动态分区分配的概念和操作过程,提升对操作系统的理解和应用能力。
在接下来的章节中,我们将分别介绍动态分区分配操作系统操作方法的背景和实验步骤,并给出相应的实例和案例分析。
最后,我们将对实验结果进行总结和展望,探讨动态分区分配操作方法的发展前景和可能的研究方向。
通过本文的阅读和实验操作,读者将能够对动态分区分配操作系统操作方法有一个全面的了解,为进一步研究和应用提供基础和指导。
同时,我们也欢迎读者对本文内容进行补充和扩展,以促进相关领域的进一步发展和应用。
1.2 文章结构文章结构部分的内容可以从以下角度进行描述:文章结构是指整篇文章的组织框架和内容安排。
合理的文章结构可以使读者更好地理解文章的主题和内容,帮助读者快速找到所需信息并形成完整的认识。
本文将按照以下结构进行论述:1. 引言:在引言部分,我们将对动态分区分配操作系统操作方法的背景和意义进行介绍,明确文章的目的和重要性。
2. 正文:正文是文章的核心部分,将分为两个要点进行叙述。
2.1 第一个要点:动态分区分配操作系统操作方法。
首先,我们将对动态分区分配的背景进行介绍,解释其在操作系统中的应用和意义。
动态分区分配方式使用的数据结构和分配算法一、引言动态分区分配是操作系统中常用的内存管理方式之一,它的主要目的是为了有效地利用计算机内存资源。
在动态分区分配中,操作系统会将可用内存空间划分为多个大小不同的连续空间,然后按照进程请求的大小来进行动态地分配和释放。
这种方式可以避免内存浪费,提高内存利用率,同时也能够保证进程访问内存时的安全性和稳定性。
二、数据结构在动态分区分配中,需要使用两个重要的数据结构:空闲块链表和已占用块链表。
1. 空闲块链表空闲块链表是指所有未被占用的内存块组成的链表。
每个节点表示一个可用块,并包含以下信息:- 块大小:表示该节点对应空闲块的大小。
- 起始地址:表示该节点对应空闲块在内存中的起始地址。
- 链接指针:指向下一个可用块节点。
2. 已占用块链表已占用块链表是指所有被进程占用的内存块组成的链表。
每个节点表示一个已占用块,并包含以下信息:- 块大小:表示该节点对应已占用块的大小。
- 进程ID:表示该节点对应已占用块所属的进程ID。
- 起始地址:表示该节点对应已占用块在内存中的起始地址。
- 链接指针:指向下一个已占用块节点。
三、分配算法动态分区分配中常用的算法有“首次适应算法”、“最佳适应算法”、“最差适应算法”等。
1. 首次适应算法首次适应算法是指从空闲块链表头开始,依次查找第一个能够满足请求大小的空闲块,并将其分配给进程。
这种方式可以快速地找到满足条件的空闲块,但可能会留下一些无法利用的小碎片。
2. 最佳适应算法最佳适应算法是指从所有可用空闲块中选择大小最合适的空闲块进行分配。
这种方式可以尽可能地利用内存资源,但需要遍历所有可用空闲块,效率较低。
3. 最差适应算法最差适应算法是指从所有可用空闲块中选择大小最大的空闲块进行分配。
这种方式可以尽可能地避免留下碎片,但也可能导致大量内存浪费。
四、动态分区分配的优缺点动态分区分配方式具有以下优点:- 可以动态地分配和释放内存,避免了内存浪费。
计算机操作系统动态分区磁盘调度算法一个好的计算机系统不仅要有足够的存储容量,较高的存取速度和稳定可靠的存储器,而且能够合理的分配和使用这些主存空间。
当用户提出申请主存空间的要求时,存储管理能够按照一定的策略分析主存的使用情况,找出足够的空间分配给申请者;当作业运行完毕,存储管理要回收作业占用的主存空间。
本实验采取可变分区存储管理方法,用常用分区管理算法模拟磁盘管理过程,以加深了解操作系统的存储管理功能。
1. 本实验是模拟操作系统的主存分配,运用可变分区的存储管理算法设计主存分配和回收程序,并不实际启动装入作业。
2. 采用最先适应法、最佳适应法、最坏适应法分配主存空间。
3. 当一个新作业要求装入主存时,必须查空闲区表,从中找出一个足够大的空闲区。
若找到的空闲区大于作业需要量,这是应把它分成二部分,一部分为占用区,加一部分又成为一个空闲区。
4. 当一个作业撤离时,归还的区域如果与其他空闲区相邻,则应合并成一个较大的空闲区,登在空闲区表中。
5. 设计的模拟系统中,进程数不小于5,进程调度方式可以采用实验一中的任何一种。
6. 运行所设计的程序,输出有关数据结构表项的变化和内存的当前状态。
首次适应算法将内存中的空闲区按照地址由低到高的顺序形成空闲区表当一个新作业要求装入主存时,查空闲区表,从中找到第一个满足要求的空闲区,为作业分配主存空间,并将剩余空闲区按照地址由小到大的顺序插入空闲区表的合适位置,修改已分配表当作业运行结束后,回收作业的主存空间,并与相邻空闲区合并,修改空闲区表和已分配表每次主存分配和回收后,打印空闲区表和已分配表详细描述实验设计思想、程序结构及各模块设计思路;详细描述程序所用数据结构及算法;明确给出测试用例和实验结果;为增加程序可读性,在程序中进行适当注释说明;认真进行实验总结,包括:设计中遇到的问题、解决方法与收获等;#include<iostream>#include<cstdlib>using namespace std;const int procsize=5;typedef struct Node{int PId; //进程Idint Prio; //进程优先数int NeedRunTime; //进程需要运行时间int Room; //进程所需空间大小Node * next; //就绪队列中的下个就绪进程的地址}PCB;typedef struct{ //就绪链式队列结构体PCB *front;PCB *rear;}AleadyQueue;typedef struct Tab{ //分区表结构体int CalledId; //调用该分区的进程Idint TabId; //分区号int Size; //大小int StartAdd; //始址char * Status; //使用状态Tab *next; //指向下个分区}Table;void CinInfo(PCB P[procsize]){ //输入进程信息cout<<"\t\t请输入5个进程,格式如下:\n\n ";cout<<"PId 优先数运行时间所需内存大小(最好是小于20)\n";int i=0,j=0;for(i,j; i<procsize ; i++,j++){cin>>P[j].PId>>P[j].Prio>>P[j].NeedRunTime>>P[j].Room;}}void Sort(PCB P[procsize]){ //根据优先数由冒泡法对进程进行排序int i,j,exchange=1; //exchange表示相邻PCB是否调换PCB Temp;for(i=procsize;i>1&&exchange;i--){exchange=0;for(j=0;j<i-1;j++)if(P[j].Prio<P[j+1].Prio){Temp=P[j];P[j]=P[j+1];P[j+1]=Temp;exchange=1;}}}AleadyQueue InitQueue(){ //就绪队列初始化函数AleadyQueue Q;Node *p;p=(Node *)malloc(sizeof(PCB));if(!p){cout<<"就绪队列初始化失败!\n";exit(0);}else{Q.front=Q.rear=p;Q.front->next=NULL;return Q;}}void EnQueue(AleadyQueue &Queue,PCB &P){ //进程入队操作函数Node *p;p=(Node *)malloc(sizeof(PCB));if(!p)cout<<"分配节点失败!\n";else {*p=P;p->next=NULL;Queue.rear->next=p;Queue.rear=p;}}void EnQueue1(AleadyQueue &Queue,PCB &P){ //进程入队操作函数Node *p;p=(Node *)malloc(sizeof(PCB));if(!p)cout<<"分配节点失败!\n";else {*p=P;p->next=NULL;Queue.rear->next=p;Queue.rear=p;}}PCB OutQueue(AleadyQueue &Q){ //进程出队操作函数Node *P;P=(Node *)malloc(sizeof(PCB));if(Q.front->next!=NULL){P=Q.front->next;Q.front->next=P->next;}return *P;}PCB OutQueue1(AleadyQueue &Q){ //进程出队操作函数Node *P;P=(Node *)malloc(sizeof(PCB));if(Q.front->next!=NULL){P=Q.front->next;Q.front->next=P->next;}return *P;}void printinfo(AleadyQueue Q){ //打印就绪队列的情况cout<<"目前就绪队列进程情况如下:\n";cout<<"PId\t\tPriority\t\tNeedTime\t\tRoom\n";Q.front=Q.front->next;while(1){if(Q.front!=NULL){cout<<Q.front->PId<<"\t\t"<<Q.front->Prio<<"\t\t\t";cout<<Q.front->NeedRunTime<<"\t\t\t"<<Q.front->Room<<endl;Q.front=Q.front->next;}elsebreak;}}int chose(){ //选择所选算法int i;cout<<"请选择:\n";cout<<" 1、采用<首次适应>算法为进程分配内存!\n";cout<<" 2、采用<最佳适应>算法为进程分配内存!\n";cout<<" 3、采用<最坏适应>算法为进程分配内存!\n";cout<<" 4、结束!\n";cin>>i;return i;}Table * CreateMMTable(){ //定义主存分区表Table * FT; //用尾插入法Table * R;Table * P;FT=(Table *)malloc(sizeof(Tab));R=FT;FT->next=NULL;int num=0;int LastAdd=0;int LastSize=1;while(1){P=(Table *)malloc(sizeof(Tab));P->CalledId=0; //被调用的进程调Id初始化为0P->TabId=num; //主存分区号P->Size=3*num+1; //分区大小P->StartAdd=LastAdd+LastSize; //分区始址P->Status="Free"; //分区状态num++; //分区号加1LastAdd=P->StartAdd; //重新定义LastAdd为上次的StartAddLastSize=P->Size; //同上P->next=NULL;R->next=P;R=P;if(P->StartAdd==93) //内存初始化完毕break;}return FT;}Table * CreateUsedTable(){ //创建已分配表Table * T;T=(Table *)malloc(sizeof(Tab));T->next=NULL;return T;}void CoutMMTable(Table * FTL){ //打印主存表情况cout<<"主存表情况:\n";cout<<"分区号\t\t"<<"分区始址\t"<<"分区大小\t"<<"状态\n";FTL=FTL->next;while(1){cout<<FTL->TabId<<"\t\t"<<FTL->StartAdd<<"\t\t";cout<<FTL->Size<<"\t\t";cout<<FTL->Status<<endl;FTL=FTL->next;if(FTL->next==NULL)break;}}void CoutFreeTable(Table * FTL){ //打印空闲区表cout<<"空闲区表情况:\n";cout<<"分区号\t\t"<<"分区始址\t"<<"分区大小\t"<<"状态\n";FTL=FTL->next;while(1){cout<<FTL->TabId<<"\t\t"<<FTL->StartAdd<<"\t\t";cout<<FTL->Size<<"\t\t";printf("%s\n",FTL->Status);FTL=FTL->next;if(FTL->next==NULL)break;}}void CoutUsedTable(Table * UTL){ //打印已分配表cout<<"已分配表情况:\n";cout<<"分区号\t\t"<<"分区始址\t"<<"分区大小\t"<<"状态\n";UTL=UTL->next;while(1){if(UTL->Status=="Used"){cout<<UTL->TabId<<"\t\t"<<UTL->StartAdd<<"\t\t";cout<<UTL->Size<<"\t\t";printf("%s\n",UTL->Status);}UTL=UTL->next;if(UTL->next==NULL)break;}}int DistribMM(Table * MMTableList,PCB Temp,Table * FTL,Table * UTL){//分配一块一定大小的内存Table *P;Table * TempMM; //需要改为已分配节点的上一个节点TempMM=MMTableList;Table * TTT;TTT=MMTableList->next;while(1){ //查找满足大小的分区节点if(TTT->Size>=Temp.Room && TTT->Status=="Free")break;TTT=TTT->next;if(TTT==NULL){cout<<"\n\n\n\t\t\t\t警告!内存不足....\n\n\n";return 0;}}//while//以下是内存改为已分配P=(Table *)malloc(sizeof(Tab));while(1){if(TempMM->next==TTT)break;TempMM=TempMM->next;}P->next=TempMM->next;TempMM->next=P;P->StartAdd=TTT->StartAdd;P->Size=Temp.Room;P->CalledId=Temp.PId;P->TabId=TTT->TabId;P->Status="Used";P=P->next;while(P!=NULL){(P->TabId)++;P=P->next;}FTL=FTL->next;while(1){ //将空闲分区对应的首地址更改if(FTL->StartAdd==TTT->StartAdd)break;FTL=FTL->next;}TTT->StartAdd=FTL->StartAdd=TTT->StartAdd+Temp.Room;//空闲表的首地址=原来+Room TTT->Size=FTL->Size=TTT->Size-Temp.Room;while(FTL!=NULL){(FTL->TabId)++;FTL=FTL->next;}return 2;}void ReturnMM(Table * MMTableList,Table * FTL,Table * UTL,PCB &Temp){ //回收一块内存MMTableList=MMTableList->next;FTL=FTL->next;Table *TT;while(1){if(MMTableList->CalledId==Temp.PId){if(MMTableList->next->Status=="Free"){MMTableList->Status="Free"; //修改内存,相邻的为FreeMMTableList->CalledId=0;MMTableList->Size=MMTableList->Size+MMTableList->next->Size;MMTableList->next=MMTableList->next->next;TT=MMTableList;while(FTL!=NULL){if(FTL->StartAdd==TT->next->StartAdd)break;FTL=FTL->next;}FTL->Size=TT->Size;}if(MMTableList->next->Status!="Free"){MMTableList->Status="Free"; //修改内存,相邻的为USedMMTableList->CalledId=0;while(FTL!=NULL){if(FTL->StartAdd==TT->next->StartAdd)break;FTL=FTL->next;}FTL->Size=TT->Size;}}if(MMTableList->next==NULL)break;MMTableList=MMTableList->next;}//总whilecout<<"\n";}int FF(Table * MMTableList,Table * FTL,Table * UTL,AleadyQueue &Q){ //首次适应算法PCB Temp;int i; //记录分配函数的返回值0int num=0; //记录进程首次分配内存while(1){Temp=OutQueue(Q);if(num<procsize){if(num==0){cout<<"正在为"<<Temp.PId<<" 号进程分配内存......\n";i=DistribMM(MMTableList,Temp,FTL,UTL); //分配内存函数if(i==0) return 0; //内存不足CoutMMTable(MMTableList); //打印主存情况CoutFreeTable(FTL); //打印空闲分区表CoutUsedTable(MMTableList); //打印已分配表}if(num==1){cout<<"正在为"<<Temp.PId<<" 号进程分配内存......\n";i=DistribMM(MMTableList,Temp,FTL,UTL); //分配内存函数if(i==0) return 0;CoutMMTable(MMTableList); //打印主存情况CoutFreeTable(FTL); //打印空闲分区表CoutUsedTable(MMTableList); //打印已分配表}if(num==2){cout<<"正在为"<<Temp.PId<<" 号进程分配内存......\n";i=DistribMM(MMTableList,Temp,FTL,UTL); //分配内存函数if(i==0) return 0; // printf("y余朝水\n");CoutMMTable(MMTableList); //打印主存情况CoutFreeTable(FTL); //打印空闲分区表CoutUsedTable(MMTableList); //打印已分配表}if(num==3){cout<<"正在为"<<Temp.PId<<" 号进程分配内存......\n";i=DistribMM(MMTableList,Temp,FTL,UTL); //分配内存函数if(i==0) return 0;CoutMMTable(MMTableList); //打印主存情况CoutFreeTable(FTL); //打印空闲分区表CoutUsedTable(MMTableList); //打印已分配表}if(num==4){cout<<"正在为"<<Temp.PId<<" 号进程分配内存......\n";i=DistribMM(MMTableList,Temp,FTL,UTL); //分配内存函数if(i==0) return 0;CoutMMTable(MMTableList); //打印主存情况CoutFreeTable(FTL); //打印空闲分区表CoutUsedTable(MMTableList); //打印已分配表}}cout<<"正在执行"<<Temp.PId<<" 号进程.....\n"; //队首调度完毕并出队Temp.Prio--; //进程优先数减1Temp.NeedRunTime--; //进程还需运行时间减1cout<<"\t\t\t目前进程"<<Temp.PId<<"的优先数: "<<Temp.Prio;cout<<" 还需运行时间: "<<Temp.NeedRunTime<<endl;num++;if(Temp.NeedRunTime==0) { //判断是否进程运行完毕,如果运行时间为0,则不再入队cout<<"\n进程"<<Temp.PId<<" 运行完成!\n";cout<<"正在回收内存......\n";if(Temp.PId==5)return 1;ReturnMM(MMTableList,FTL,UTL,Temp); //回收内存CoutMMTable(MMTableList); //打印主存情况CoutFreeTable(FTL); //打印空闲分区表CoutUsedTable(MMTableList); //打印已分配表printinfo(Q);if(Q.front->next==NULL) //判断就绪队列是否为空break;}elseEnQueue(Q,Temp); //运行时间不为0,还需入队等待下一个时间片再次执行}return 2;}int BF(Table * MMTableList,Table * FTL,Table * UTL,AleadyQueue &Q2){ //最佳适应算法PCB P[procsize]; //定义五个进程CinInfo(P); //输入进程信息Sort(P); //根据优先数的大小进行排序,形成进程数组PQ2=InitQueue(); //就绪队列初始化for(int k=0; k<procsize; k++)EnQueue(Q2,P[k]);int i; //记录分配函数的返回值0int num=0;PCB Temp;while(1){Temp=OutQueue1(Q2);if(num<procsize){if(num==0){cout<<"正在为"<<Temp.PId<<"进程分配内存......\n";cout<<"...........................\n\n";}if(num==1){cout<<"正在为"<<Temp.PId<<"进程分配内存......\n";cout<<"...........................\n\n";}if(num==2){cout<<"正在为"<<Temp.PId<<"进程分配内存......\n";cout<<"...........................\n\n";}if(num==3){cout<<"正在为"<<Temp.PId<<"进程分配内存......\n";cout<<"...........................\n\n";}if(num==4){cout<<"正在为"<<Temp.PId<<"进程分配内存......\n";cout<<"...........................\n\n";}}cout<<"正在执行"<<Temp.PId<<" 号进程.....\n"; //队首调度完毕并出队Temp.Prio--; //进程优先数减1Temp.NeedRunTime--; //进程还需运行时间减1cout<<"\t\t\t目前进程"<<Temp.PId<<"的优先数: "<<Temp.Prio;cout<<" 还需运行时间: "<<Temp.NeedRunTime<<endl;num++;if(Temp.NeedRunTime==0) { //判断是否进程运行完毕,如果运行时间为0,则不再入队cout<<"\n进程"<<Temp.PId<<" 运行完成!\n";cout<<"正在回收内存......\n";cout<<"...........................\n\n";if(Q2.front->next==NULL) //判断就绪队列是否为空break;}elseEnQueue1(Q2,Temp); //运行时间不为0,还需入队等待下一个时间片再次执行}return 1;}int WF(Table * MMTableList,Table * FTL,Table * UTL,AleadyQueue &Q2){ //最坏适应算法PCB P[procsize]; //定义五个进程CinInfo(P); //输入进程信息Sort(P); //根据优先数的大小进行排序,形成进程数组P Q2=InitQueue(); //就绪队列初始化for(int k=0; k<procsize; k++)EnQueue(Q2,P[k]);int i; //记录分配函数的返回值0int num=0;PCB Temp;while(1){Temp=OutQueue1(Q2);if(num<procsize){if(num==0){cout<<"正在为"<<Temp.PId<<"进程分配内存......\n";cout<<"...........................\n\n";}if(num==1){cout<<"正在为"<<Temp.PId<<"进程分配内存......\n";cout<<"...........................\n\n";}if(num==2){cout<<"正在为"<<Temp.PId<<"进程分配内存......\n";cout<<"...........................\n\n";}if(num==3){cout<<"正在为"<<Temp.PId<<"进程分配内存......\n";cout<<"...........................\n\n";}if(num==4){cout<<"正在为"<<Temp.PId<<"进程分配内存......\n";cout<<"...........................\n\n";}}cout<<"正在执行"<<Temp.PId<<" 号进程.....\n"; //队首调度完毕并出队Temp.Prio--; //进程优先数减1Temp.NeedRunTime--; //进程还需运行时间减1cout<<"\t\t\t目前进程"<<Temp.PId<<"的优先数: "<<Temp.Prio;cout<<" 还需运行时间: "<<Temp.NeedRunTime<<endl;num++;if(Temp.NeedRunTime==0) { //判断是否进程运行完毕,如果运行时间为0,则不再入队cout<<"\n进程"<<Temp.PId<<" 运行完成!\n";cout<<"正在回收内存......\n";cout<<"...........................\n\n";if(Q2.front->next==NULL) //判断就绪队列是否为空break;}elseEnQueue1(Q2,Temp); //运行时间不为0,还需入队等待下一个时间片再次执行}return 2;}void main(){AleadyQueue Q1; //定义一个就绪队列AleadyQueue Q2;AleadyQueue Q3;PCB P[procsize]; //定义五个进程CinInfo(P); //输入进程信息Sort(P); //根据优先数的大小进行排序,形成进程数组P Q1=InitQueue(); //就绪队列初始化Q2=InitQueue();Q3=InitQueue();for(int k=0; k<procsize; k++)EnQueue(Q1,P[k]); //首次排好序的就绪进程入队,//进程依次等待处理机调度for(k=0; k<procsize; k++)EnQueue(Q2,P[k]);for(k=0; k<procsize; k++)EnQueue(Q3,P[k]);printinfo(Q1); //打印当前就绪队列的情况Q3=Q2=Q1;Table * MMTableList; //主存分区表Table * MM;Table * FreeTableList; //空闲分区表Table * UsedTableList; //已分配分区表MMTableList=CreateMMTable(); //创建主存分区表MM=CreateMMTable();FreeTableList=CreateMMTable(); //创建空闲分区表(初始化时和内存分区表相同)UsedTableList=CreateUsedTable(); //创建已分配表CoutMMTable(MMTableList); //打印主存分区表int i; //记录0,内存不足int j; //记录所选算法while(1){j=chose(); //判断所选算法,所需操作(FF、BF、WF)if(j==1)i=FF(MM,FreeTableList,UsedTableList,Q1);//首次适应算法if(i==0)exit(0); //内存不足if(j==2)i=BF(MM,FreeTableList,UsedTableList,Q2);//最佳适应算法if(i==0)exit(0); //内存不足if(j==3)i=WF(MM,FreeTableList,UsedTableList,Q3);//最坏适应算法if(i==0)exit(0); //内存不足if(j==4)break; //结束内存分配}cout<<"\n\n\n-----------------------------------欢迎使用!------------------------------------\n\n\n\n\n"; }。
动态分区分配算法动态分区分配算法是在计算机内存管理中使用的一种内存分配策略。
在动态分区分配算法下,内存被划分为多个大小不一的分区,每个分区可以用来存储不同大小的进程。
当一个进程需要内存时,系统会选择一个合适的分区来满足其需求。
动态分区分配算法有多种实现方式,常用的包括最先适应算法、最佳适应算法和最坏适应算法。
最先适应算法(First Fit)是最简单和最常用的动态分区分配算法之一、该算法从内存起始位置开始查找合适的分区,一旦找到一个大小大于等于所需内存大小的空闲分区,就将该进程分配给这个分区并将分区大小减去所需内存大小。
这种算法的优点是实现简单、分区利用率高,但它可能会导致较小的分区被浪费掉,从而导致外部碎片的产生。
最佳适应算法(Best Fit)是另一种常用的动态分区分配算法。
该算法从所有空闲分区中选择一个大小最适合所需内存大小的分区来分配。
相比于最先适应算法,最佳适应算法能够更好地利用内存分区,减少外部碎片的产生。
然而,该算法的实现相对复杂,并且容易产生许多较小的空闲分区,导致分区利用率降低。
最坏适应算法(Worst Fit)是另一种动态分区分配算法。
该算法选择一个大小最大的空闲分区来分配给进程,这样可以留下更多较小的空闲分区,以备将来的进程使用。
然而,最坏适应算法可能会导致较大的分区被浪费掉,从而导致外部碎片的产生。
同样,该算法的实现也相对复杂,并且分区利用率相对较低。
动态分区分配算法的选择取决于特定的应用和场景。
最先适应算法在分配速度和分区利用率方面可能更优,但可能会产生较多的外部碎片。
最佳适应算法能够更好地利用内存分区,但实现复杂,容易产生较小的空闲分区。
最坏适应算法留下较小的空闲分区,但分区利用率较低。
因此,在选择动态分区分配算法时,需要权衡这些因素,并根据特定需求进行选择。
动态分区分配算法在现代操作系统中起着重要的作用,可以有效管理内存资源,提高系统的性能和效率。
同时,动态分区分配算法也是操作系统中的一个重要研究领域,不断有新的技术和算法被提出来优化内存管理,满足日益复杂的应用需求。
存储管理动态分区分配及回收算法⼀、实验⽬的分区管理是应⽤较⼴泛的⼀种存储管理技术。
本实验要求⽤⼀种结构化⾼级语⾔构造分区描述器,编制动态分区匹配算法和回收算法模拟程序,并讨论不同算法的特点。
⼆、实验内容1.编写:First Fit Algorithm2.编写:Best Fit Algorithm3.编写 :空闲区回收算法三,提⽰和说明(⼀)主程序1、定义分区描述器node,包括 3个元素:(1)adr——分区⾸地址(2)size——分区⼤⼩(3)next——指向下⼀个分区的指针2、定义 3个指向node结构的指针变量:(1)head1——空闲区队列⾸指针(2)back1——指向释放区node结构的指针(3)assign——指向申请的内存分区node结构的指针3、定义 1个整形变量:free——⽤户申请存储区的⼤⼩(由⽤户键⼊)(⼆)过程1、定义check过程,⽤于检查指定的释放块(由⽤户键⼊)的合法性2、定义assignment1过程,实现First Fit Algorithm3、定义assignment2过程,实现Best Fit Algorithm4、定义acceptment1过程,实现First Fit Algorithm的回收算法5、定义acceptment2过程,实现Best Fit Algorithm的回收算法6、定义print过程,打印空闲区队列(三)执⾏程序⾸先申请⼀整块空闲区,其⾸址为0,⼤⼩为32767;然后,提⽰⽤户使⽤哪种分配算法,再提⽰是分配还是回收;分配时要求输⼊申请区的⼤⼩,回收时要求输⼊释放区的⾸址和⼤⼩。
(四)输出要求每执⾏⼀次,输出⼀次空闲区队列情况,内容包括:编号⾸址终址⼤⼩三、实验过程1.准备A.查阅相关资料;B.初步编写程序;C.准备测试数据;2、主要流程和源代码#include<iostream>#include<stdlib.h>using namespace std;#define Free 0 //空闲状态#define Busy 1 //已⽤状态#define OK 1 //完成#define ERROR 0 //出错#define MAX_length 32767 //最⼤内存空间为32767KB typedef int Status;int n = 0;typedef struct freearea//定义⼀个空闲区说明表结构{int ID; //分区号long size; //分区⼤⼩long address; //分区地址int state; //状态}ElemType;//线性表的双向链表存储结构typedef struct DuLNode //double linked list{ElemType data;struct DuLNode *prior; //前趋指针struct DuLNode *next; //后继指针}DuLNode, *DuLinkList;DuLinkList block_first; //头结点DuLinkList block_last; //尾结点Status alloc(int);//内存分配Status free(int); //内存回收Status First_fit(int, int);//⾸次适应算法Status Best_fit(int, int); //最佳适应算法void show();//查看分配Status Initblock();//开创空间表Status Initblock()//开创带头结点的内存空间链表{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;block_last->data.size = MAX_length;block_last->data.ID = 0;block_last->data.state = Free;return OK;}//分配主存Status alloc(int ch){int ID, request;cout << "请输⼊作业(分区号):";cin >> ID;cout << "请输⼊需要分配的主存⼤⼩(单位:KB):";cin >> request;if (request<0 || request == 0){cout << "分配⼤⼩不合适,请重试!" << endl;return ERROR;}if (ch == 2) //选择最佳适应算法{if (Best_fit(ID, request) == OK) cout << "分配成功!" << endl; else cout << "内存不⾜,分配失败!" << endl;return OK;}else //默认⾸次适应算法{if (First_fit(ID, request) == OK) cout << "分配成功!" << endl; else cout << "内存不⾜,分配失败!" << endl;return OK;}}//⾸次适应算法Status First_fit(int ID, int request)//传⼊作业名及申请量{//为申请作业开辟新空间且初始化DuLinkList temp = (DuLinkList)malloc(sizeof(DuLNode)); temp->data.ID = ID;temp->data.size = request;DuLNode *p = block_first->next;while (p){if (p->data.state == Free && p->data.size == request) {//有⼤⼩恰好合适的空闲块p->data.state = Busy;p->data.ID = ID;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 Best_fit(int ID, int request){int ch; //记录最⼩剩余空间DuLinkList temp = (DuLinkList)malloc(sizeof(DuLNode)); temp->data.ID = ID;temp->data.size = request;temp->data.state = Busy;DuLNode *p = block_first->next;DuLNode *q = NULL; //记录最佳插⼊位置while (p) //初始化最⼩空间和最佳位置{(p->data.size>request || p->data.size == request)){q = p;ch = p->data.size - request;break;}p = p->next;}while (p){if (p->data.state == Free && p->data.size == request) {//空闲块⼤⼩恰好合适p->data.ID = ID;p->data.state = Busy;return OK;break;}if (p->data.state == Free && p->data.size>request) {//空闲块⼤于分配需求if (p->data.size - request<ch)//剩余空间⽐初值还⼩{ch = p->data.size - request;//更新剩余最⼩值q = p;//更新最佳位置指向}}p = p->next;}if (q == NULL) return ERROR;//没有找到空闲块else{//找到了最佳位置并实现分配temp->prior = q->prior;temp->next = q;temp->data.address = q->data.address;q->prior->next = temp;q->prior = temp;q->data.address += request;q->data.size = ch;return OK;}}//主存回收Status free(int ID){DuLNode *p = block_first;while (p){if (p->data.ID == ID){p->data.state = Free;p->data.ID = Free;if (p->prior->data.state == Free)//与前⾯的空闲块相连{p->prior->data.size += p->data.size;p->prior->next = p->next;p->next->prior = p->prior;}if (p->next->data.state == Free)//与后⾯的空闲块相连{p->data.size += p->next->data.size;p->next->next->prior = p;p->next = p->next->next;}break;}p = p->next;}return OK;}// 显⽰主存分配情况void show(){cout << "***********-----------------************" << endl; cout << "**** 主存分配情况 ****" << endl; cout << "***********-----------------************" << endl; DuLNode *p = block_first->next;while (p){cout << "分区号:";if (p->data.ID == Free) cout << "Free" << endl;else cout << p->data.ID << endl;cout << "起始地址:" << p->data.address << endl;cout << "分区⼤⼩:" << p->data.size << " KB" << endl; cout << "状态:";if (p->data.state == Free) cout << "空闲" << endl;else cout << "已分配!" << endl;cout << "-----------------------" << endl;p = p->next;}}//主函数int main(){int ch, d = 0;//算法选择标记cout << "1.⾸次适应算法 2.最佳适应算法 0.退出" << endl; cout << "请选择分配算法:";cin >> ch;if (ch == 0 || ch == 1 || ch == 2) d++;while (d == 0){cout << "请选择正确的数字0 ,1 或2" << endl;cin >> ch;if (ch == 0 || ch == 1 || ch == 2) d++;}if (ch == 0) exit(0);if (n == 0) Initblock(); //开创空间表int choice; //操作选择标记while (1){cout << "********************************************" << endl; cout << "** 1: 分配内存 2: 回收内存 **" << endl; cout << "** 3: 查看分配 0: 返回 **" << endl; cout << "********************************************" << endl; cout << "请输⼊您的操作:";cin >> choice;if (choice == 1)alloc(ch); // 分配内存n++;}else if (choice == 2) // 内存回收{int ID;cout << "请输⼊您要释放的分区号:"; cin >> ID;free(ID);n++;}else if (choice == 3){show();//显⽰主存n++;}else if (choice == 0){main(); //退出n++;}else //输⼊操作有误{cout << "输⼊有误,请重试!" << endl; continue;}}}四、实验结果3、遇到的主要问题和解决⽅法主要问题是在算法的结构的理解。
动态分区分配方式使用的数据结构和分配算法1. 引言动态分区分配方式是操作系统中一种常用的内存管理方式,它将内存划分为多个动态大小的分区,根据程序的需要进行动态分配和释放。
本文将介绍动态分区分配方式使用的数据结构和分配算法。
2. 数据结构在动态分区分配方式中,需要使用以下数据结构来管理内存空间:2.1 空闲块链表空闲块链表是一个双向链表,用于记录当前可用的内存空间。
每个节点表示一个空闲块,包含以下字段: - 起始地址:表示该空闲块在内存中的起始地址。
- 大小:表示该空闲块的大小。
- 前驱指针:指向前一个空闲块节点。
- 后继指针:指向后一个空闲块节点。
通过维护这个链表,可以高效地查找和管理可用的内存空间。
2.2 分配表分配表是一个数组,用于记录当前已经被程序占用的内存空间。
每个元素表示一个已经被占用的内存块,包含以下字段: - 起始地址:表示该内存块在内存中的起始地址。
- 大小:表示该内存块的大小。
- 进程ID:表示占用该内存块的进程ID。
通过维护这个数组,可以方便地查找和管理已经被程序占用的内存空间。
3. 分配算法在动态分区分配方式中,需要使用一种合适的算法来进行内存分配。
常用的分配算法有以下几种:3.1 首次适应算法(First Fit)首次适应算法是最简单和最常用的分配算法之一。
它从空闲块链表中找到第一个大小大于等于所需大小的空闲块,并将其分割成两部分,一部分满足程序需求,另一部分仍然是空闲块。
该算法具有以下特点: - 实现简单,时间复杂度较低。
- 分配效率较高,但可能会导致碎片问题。
3.2 最佳适应算法(Best Fit)最佳适应算法是一种比较高效的分配算法。
它从空闲块链表中找到大小最接近所需大小的空闲块,并将其分割成两部分。
该算法具有以下特点: - 分配效果较好,能够尽量减少碎片问题。
- 时间复杂度较高,需要遍历整个空闲块链表。
3.3 最坏适应算法(Worst Fit)最坏适应算法是一种相对较差的分配算法。
实验容:存储器管理实验一、实验目的采用首次适应算法(FF),最佳适应算法(BF),最坏适应算法(WF)三种不同的算法,实现对系统空闲区的动态分区分配。
二、实验题目给予顺序搜索的动态分区算法的程序。
三、实验要求读懂给出的核心代码,进行适当的修改,编译通过后,完成实验报告。
四、核心代码#include <stdio.h>#include <stdlib.h>#include <malloc.h>//常量定义#define PROCESS_NAME_LEN 32#define MIN_SLICE 10#define DEFAULT_MEM_SIZE 1024#define DEFAULT_MEM_START 0#define MA_FF 1#define MA_BF 2#define MA_WF 3int mem_size=DEFAULT_MEM_SIZE;int ma_algorithm = MA_FF;static int pid = 0;int flag = 0;struct free_block_type{int size;int start_addr;struct free_block_type *next;};struct free_block_type *free_block;//描述已分配的存块struct allocated_block{int pid; int size;int start_addr;char process_name[PROCESS_NAME_LEN];struct allocated_block *next;};struct allocated_block *allocated_block_head = NULL;//函数声明struct free_block_type* init_free_block(int mem_size);void display_menu();int set_mem_size();void set_algorithm();void rearrange(int algorithm);int rearrange_FF();int rearrange_BF();int rearrange_WF();int new_process();int allocate_mem(struct allocated_block *ab);void kill_process();int free_mem(struct allocated_block *ab);int dispose(struct allocated_block *free_ab);int display_mem_usage();void do_exit();struct allocated_block *find_process(int pid);int main(){char choice; pid=0;free_block= init_free_block(mem_size); //初始化空闲区while(1) {display_menu(); //显示菜单fflush(stdin);choice=getchar(); //获取用户输入switch(choice){case '1': set_mem_size(); break; //设置存大小case '2': set_algorithm();flag=1; break;//设置算法case '3': new_process(); flag=1; break;//创建新进程case '4': kill_process(); flag=1; break;//删除进程case '5': display_mem_usage(); flag=1; break; //显示存使用case '0': do_exit(); exit(0); //释放链表并退出default: break;}}return 1;}struct free_block_type* init_free_block(int mem_size){struct free_block_type *fb;fb=(struct free_block_type *)malloc(sizeof(struct free_block_type));if(fb==NULL){printf("No mem\n");return NULL;}fb->size = mem_size;fb->start_addr = DEFAULT_MEM_START;fb->next = NULL;return fb;}void display_menu(){printf("\n");printf("1 - Set memory size (default=%d)\n", DEFAULT_MEM_SIZE);printf("2 - Select memory allocation algorithm\n");printf("3 - New process \n");printf("4 - Terminate a process \n");printf("5 - Display memory usage \n");printf("0 - Exit\n");}int set_mem_size(){int size;if(flag!=0){ //防止重复设置printf("Cannot set memory size again\n");return 0;}printf("Total memory size =");scanf("%d", &size);if(size>0) {mem_size = size;free_block->size = mem_size;}flag=1;return 1;}void set_algorithm(){int algorithm;while(1) {printf("\t1 - First Fit\n");printf("\t2 - Best Fit \n");printf("\t3 - Worst Fit \n");scanf("%d", &algorithm);if(algorithm>=1 && algorithm <=3) {ma_algorithm = algorithm;break;}elseprintf("输入有误,请重新输入!\n");}//按指定算法重新排列空闲区链表rearrange(ma_algorithm);}void rearrange(int algorithm){switch(algorithm){case MA_FF: rearrange_FF(); break;case MA_BF: rearrange_BF(); break;case MA_WF: rearrange_WF(); break;}}//首次适应算法int rearrange_FF(){struct free_block_type *temp;//使用头插法,thead为临时头,p为最小地址的数据块的前一个结点struct free_block_type *thead=NULL,*p=NULL;//当前的最小地址int min_addr = free_block->start_addr;temp = free_block;while(temp->next!=NULL) {if(temp->next->start_addr<min_addr) {min_addr = temp->next->start_addr;p = temp;}temp = temp->next;}if(NULL!=p) {temp = p->next;p->next = p->next->next;temp->next = free_block;free_block = temp;}thead = free_block;p = free_block;temp = free_block->next;while(thead->next!=NULL) {min_addr = thead->next->start_addr;while(temp->next!=NULL) {if(temp->next->start_addr<min_addr) {min_addr = temp->next->start_addr;p = temp;}temp = temp->next;}if(p->next!=thead->next) {temp = p->next;p->next = p->next->next;temp->next = thead->next;thead->next = temp;}thead = thead->next;p = thead;temp = thead->next;}return 1;}//最佳适应算法int rearrange_BF(){struct free_block_type *temp;//使用头插法,thead为临时头,p为最小存的数据块的前一个结点struct free_block_type *thead=NULL,*p=NULL;//当前的最小存int min_size = free_block->size;temp = free_block;while(temp->next!=NULL) {if(temp->next->size<min_size) {min_size = temp->next->size;p = temp;}temp = temp->next;}if(NULL!=p) {temp = p->next;p->next = p->next->next;temp->next = free_block;free_block = temp;}thead = free_block;p = free_block;temp = free_block->next;while(thead->next!=NULL) {min_size = thead->next->size;while(temp->next!=NULL) {if(temp->next->size<min_size) {min_size = temp->next->size;p = temp;}temp = temp->next;}if(p->next!=thead->next) {temp = p->next;p->next = p->next->next;temp->next = thead->next;thead->next = temp;}thead = thead->next;p = thead;temp = thead->next;}return 1;}//最坏适应算法int rearrange_WF(){struct free_block_type *temp;//使用头插法,thead为临时头,p为最大存的数据块的前一个结点struct free_block_type *thead=NULL,*p=NULL;//当前的最大存int max_size = free_block->size;temp = free_block;while(temp->next!=NULL) {if(temp->next->size>max_size) {max_size = temp->next->size;p = temp;}temp = temp->next;}if(NULL!=p) {temp = p->next;p->next = p->next->next;temp->next = free_block;free_block = temp;}thead = free_block;p = free_block;temp = free_block->next;while(thead->next!=NULL) {max_size = thead->next->size;while(temp->next!=NULL) {if(temp->next->size>max_size) {max_size = temp->next->size;p = temp;}temp = temp->next;}if(p->next!=thead->next) {temp = p->next;p->next = p->next->next;temp->next = thead->next;thead->next = temp;}thead = thead->next;p = thead;temp = thead->next;}return 1;}int new_process(){struct allocated_block *ab;int size;int ret;ab = (struct allocated_block *)malloc(sizeof(struct allocated_block));if(!ab) exit(-5);ab->next = NULL;pid++;sprintf(ab->process_name, "PROCESS-d", pid);ab->pid = pid;while(1) {printf("Memory for %s:", ab->process_name);scanf("%d", &size);if(size>0) {ab->size=size;break;}else printf("输入大小有误,请重新输入\n");}ret = allocate_mem(ab);if((ret==1) &&(allocated_block_head == NULL)){allocated_block_head=ab;return 1;}else if (ret==1) {ab->next = allocated_block_head;allocated_block_head = ab;return 2; }else if(ret==-1){printf("Allocation fail\n");pid--;free(ab);return -1;}return 3;}int allocate_mem(struct allocated_block *ab){struct free_block_type *fbt, *pre,*head,*temp,*tt;struct allocated_block *tp;int request_size=ab->size;int sum=0;int max;head = (struct free_block_type *)malloc(sizeof(struct free_block_type));pre = head;fbt = free_block;pre->next = fbt;if(ma_algorithm==MA_WF) {if(NULL==fbt||fbt->size<request_size)return -1;}else {while(NULL!=fbt&&fbt->size<request_size) {pre = fbt;fbt = fbt->next;}}if(NULL==fbt||fbt->size<request_size) {if(NULL!=free_block->next) {sum = free_block->size;temp = free_block->next;while(NULL!=temp) {sum += temp->size;if(sum>=request_size)break;temp = temp->next;}if(NULL==temp)return -1;else {pre = free_block;max = free_block->start_addr;fbt = free_block;while(temp->next!=pre) {if(max<pre->start_addr) {max = pre->start_addr;fbt = pre;}pre = pre->next;}pre = free_block;while(temp->next!=pre) {tp = allocated_block_head;tt = free_block;if(pre!=fbt) {while(NULL!=tp) {if(tp->start_addr>pre->start_addr)tp->start_addr = tp->start_addr - pre->size;tp = tp->next;}while(NULL!=tt) {if(tt->start_addr>pre->start_addr)tt->start_addr = tt->start_addr - pre->size;tt = tt->next;}}pre = pre->next;}pre = free_block;while(pre!=temp->next) {if(pre!=fbt)free(pre);pre = pre->next;}free_block = fbt;free_block->size = sum;free_block->next = temp->next;if(free_block->size - request_size < MIN_SLICE) {ab->size = free_block->size;ab->start_addr = free_block->start_addr;pre = free_block;free_block = free_block->next;free(pre);}else {ab->start_addr = fbt->start_addr;free_block->start_addr = free_block->start_addr + request_size;free_block->size = free_block->size - request_size;}}}elsereturn -1;}else {//将存块全部分配if(fbt->size - request_size < MIN_SLICE) {ab->size = fbt->size;ab->start_addr = fbt->start_addr;if(pre->next==free_block) {free_block = fbt->next;}elsepre->next = fbt->next;free(fbt);}else {ab->start_addr = fbt->start_addr;fbt->start_addr = fbt->start_addr + request_size;fbt->size = fbt->size - request_size;}}free(head);rearrange(ma_algorithm);return 1;}void kill_process(){struct allocated_block *ab;int pid;printf("Kill Process, pid=");scanf("%d", &pid);ab = find_process(pid);if(ab!=NULL){free_mem(ab);dispose(ab);}else {printf("没有pid为%d的进程!\n",pid);}}struct allocated_block *find_process(int pid) {struct allocated_block *ab=NULL;ab = allocated_block_head;while(NULL!=ab&&ab->pid!=pid)ab = ab->next;return ab;}int free_mem(struct allocated_block *ab){int algorithm = ma_algorithm;struct free_block_type *fbt, *pre=NULL,*head;fbt=(struct free_block_type*) malloc(sizeof(struct free_block_type));pre=(struct free_block_type*) malloc(sizeof(struct free_block_type));if(!fbt) return -1;// 进行可能的合并,基本策略如下// 1. 将新释放的结点插入到空闲分区队列末尾// 2. 对空闲链表按照地址有序排列// 3. 检查并合并相邻的空闲分区// 4. 将空闲链表重新按照当前算法排序head = pre;fbt->start_addr = ab->start_addr;fbt->size = ab->size;fbt->next = free_block; //新释放的结点插入到空闲分区链表的表头free_block = fbt;rearrange_FF(); //对空闲链表按照地址有序排列pre->next = free_block; //求的pre为fbt的前一个结点pre->size = 0;while(pre->next->start_addr!=fbt->start_addr)pre = pre->next;//左右分区都存在if(0!=pre->size&&NULL!=fbt->next) {//左右分区都可合并if((pre->start_addr+pre->size)==fbt->start_addr && (fbt->start_addr+fbt->size)==fbt->next->start_addr) {pre->size = pre->size + fbt->size + fbt->next->size;pre->next = fbt->next->next;free(fbt->next);free(fbt);}//左分区可合并else if((pre->start_addr+pre->size)==fbt->start_addr) {pre->size = pre->size + fbt->size;pre->next = fbt->next;free(fbt);}//右分区可合并else if((fbt->start_addr+fbt->size)==fbt->next->start_addr) {fbt->size = fbt->size + fbt->next->size;fbt->next = fbt->next->next;free(fbt->next);}}//左分区不存在else if(0==pre->size) {if((fbt->start_addr+fbt->size)==fbt->next->start_addr) {fbt->size = fbt->size + fbt->next->size;fbt->next = fbt->next->next;free(fbt->next);}}//右分区不存在else if(NULL==fbt->next) {if((pre->start_addr+pre->size)==fbt->start_addr) {pre->size = pre->size + fbt->size;pre->next = fbt->next;free(fbt);}}rearrange(algorithm);free(head);return 1;}int dispose(struct allocated_block *free_ab){struct allocated_block *pre, *ab;if(free_ab == allocated_block_head) {allocated_block_head = allocated_block_head->next;free(free_ab);return 1;}pre = allocated_block_head;ab = allocated_block_head->next;while(ab!=free_ab){ pre = ab; ab = ab->next; }pre->next = ab->next;free(ab);return 2;}int display_mem_usage(){struct free_block_type *fbt=free_block;struct allocated_block *ab=allocated_block_head;if(fbt==NULL) return(-1);printf("----------------------------------------------------------\n");printf("Free Memory:\n");printf(" s s\n", " start_addr", " size");while(fbt!=NULL){printf(" d d\n", fbt->start_addr, fbt->size);fbt=fbt->next;}printf("\nUsed Memory:\n");printf("s s s s\n", "PID", "ProcessName", "start_addr", " size");while(ab!=NULL){printf("d s d d\n", ab->pid, ab->process_name, ab->start_addr, ab->size);ab=ab->next;}printf("----------------------------------------------------------\n");return 0;}void do_exit() {}。