实验四动态分区分配算法
- 格式: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:总结与自评:总结:分区存储管理是操作系统进行内存管理的一种方式。
实验容:存储器管理实验一、实验目的采用首次适应算法(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() {}。