操作系统实验四报告-主存空间分配和回收(含源码)分析

合集下载

实验四 主存储器空间的分配和回收

实验四  主存储器空间的分配和回收

漳州师范学院实验报告班级 11网络2班学号姓名座号 15 同组人实验日期成绩课程名称:操作系统实验题目:主存储器空间的分配和回收实验目的与要求PC 兼容机。

Window xp 以上操作系统实验环境的配置第 1 页实验内容与具体步骤实验内容与具体步骤源代码如下:#include <stdio.h>#include <stdlib.h>#include <iostream.h>#define n 10 //模拟实验中,允许的最大作业数目#define m 10 //模拟实验中,允许的最大空间分区数目#define minisize 100 /*该空闲区低于该值,可视为碎片。

分配分区时,若寻找到的最小适合空间相对作业请求的空间来说仍大于该数值,则要分割该分区,但是分割后,空闲为很小,变成碎片,则不分割。

*/struct{float address; //已分配分区起始地址float length; //已分配分区长度,单位为字符int flag; //0表明为空闲的。

否则为已分配,记录作业的名称。

}used_table[n];//已分配分区表struct{ float address;float length;int flag;//0表示是空表目,否则1表示空闲分区为"未分配"}free_table[m];void allocate(char job,float xk){ //该内存分配算法,采用是最优适应算法,int i,k; float ad; k=-1;for(i=0;i<=m;i++)if(free_table[i].length>=xk&&free_table[i].flag==1)//通过该循环,先找到最小分区if(k==-1||free_table[i].length<free_table[k].length)k=i;//用变量k来存放最小的分区的下标if(k==-1){ printf("Allocation failure!\n");return;}if(free_table[k].length-xk<=minisize){//不需分割的情况,用变量ad和xk存放将分配出去空闲区的地址和长度free_table[k].flag=0;ad=free_table[k].address;xk=free_table[k].length;}else{//若寻找到的最小适合空间相对作业请求的空间来说仍过大,则进行分割分区。

主存空间的分配与回收实验报告

主存空间的分配与回收实验报告
1、实验目的:
熟悉主存的分配与回收。理解在不同的存储管理方式下,如何实现主存空 间的分配与回收。掌握动态分区分配方式中的数据结构和分配算法及动态分区 存储管理方式及其实现过程。
2、实验要求
实验要求使用可变分区存储管理方式,分区分配中所用的数据结构采用空 闲分区表和空闲分区链来进行,分区分配中所用的算法采用首次适应算法、循 环首次适应算法、最佳适应算法三种算法来实现主存的分配与回收。同时,要 求设计一个实用友好的用户界面,并显示分配与回收的过程。
主存空间的分配与回 收实验报告
用心整理的精品 word 文档,下载即可编辑!!
实验报告
课程名称: 操作系统
实验名称: 主存空间的分配与回收

号: 110310014
学生姓名: 于钊

级: 信管 1101 班
指导教师: 吴联世
实验日期: 2013 年 12 月 5 日
2 精心整理,用心做精品
用心整理的精品 word 文档,下载即可编辑!!
1. 设计记录主存使用情况的数据表格 由 于动态分区的大小是由作业需求量决定的,故分区的长度是预先不固定的, 且分区的个数也随主存分配和回收变动。总之,所有分区情况随时可能发生变 化,数据表 格的设计必须和这个特点相适应。由于分区长度不同,因此设计的 表格应该包括分区在主存中的起始地址和长度。由于分配时,空闲区有时会变 成两个分区:空闲区 和已分分区,回收主存分区时,可能会合并空闲区,这样 如果整个主存采用一张表格记录已分分区和空闲区,就会使表格操作繁琐。主 存分配时查找空闲区进行分 配,然后填写已分配区表,主要操作在空闲区;某 个作业执行完后,将该分区贬词空闲区,并将其与相邻的空闲区合并,主要操 作也在空闲区。由此可见,主存的分 配与回收主要时对空闲区的操作。这样为 了便于对主存空间的分配与回收,就建立两张分区表记录主存的使用情况:“已 分配区表”记录作业占用分区,“空闲区 表”记录空闲区。

实验四 操作系统存储管理实验报告

实验四  操作系统存储管理实验报告

实验四操作系统存储管理实验报告一、实验目的本次操作系统存储管理实验的主要目的是深入理解操作系统中存储管理的基本原理和方法,通过实际操作和观察,掌握内存分配、回收、地址转换等关键技术,提高对操作系统存储管理机制的认识和应用能力。

二、实验环境操作系统:Windows 10开发工具:Visual Studio 2019三、实验原理1、内存分配方式连续分配:分为单一连续分配和分区式分配(固定分区和动态分区)。

离散分配:分页存储管理、分段存储管理、段页式存储管理。

2、内存回收算法首次适应算法:从内存低地址开始查找,找到第一个满足要求的空闲分区进行分配。

最佳适应算法:选择大小最接近作业需求的空闲分区进行分配。

最坏适应算法:选择最大的空闲分区进行分配。

3、地址转换逻辑地址到物理地址的转换:在分页存储管理中,通过页表实现;在分段存储管理中,通过段表实现。

四、实验内容及步骤1、连续内存分配实验设计一个简单的内存分配程序,模拟固定分区和动态分区两种分配方式。

输入作业的大小和请求分配的分区类型,程序输出分配的结果(成功或失败)以及分配后的内存状态。

2、内存回收实验在上述连续内存分配实验的基础上,添加内存回收功能。

输入要回收的作业号,程序执行回收操作,并输出回收后的内存状态。

3、离散内存分配实验实现分页存储管理的地址转换功能。

输入逻辑地址,程序计算并输出对应的物理地址。

4、存储管理算法比较实验分别使用首次适应算法、最佳适应算法和最坏适应算法进行内存分配和回收操作。

记录不同算法在不同作业序列下的内存利用率和分配时间,比较它们的性能。

五、实验结果与分析1、连续内存分配实验结果固定分区分配方式:在固定分区大小的情况下,对于作业大小小于或等于分区大小的请求能够成功分配,否则分配失败。

内存状态显示清晰,分区的使用和空闲情况一目了然。

动态分区分配方式:能够根据作业的大小动态地分配内存,但容易产生内存碎片。

2、内存回收实验结果成功回收指定作业占用的内存空间,内存状态得到及时更新,空闲分区得到合并,提高了内存的利用率。

操作系统实验--主存空间的分配和回收

操作系统实验--主存空间的分配和回收

主存空间的分配与回收#include"stdio.h"#include"stdlib.h"#define n 10 /*假定系统允许的最大作业为n,假定模拟实验中n 值为10*/#define m 10 /*假定系统允许的空闲区表最大为m,假定模拟实验中m值为10*/#define minisize 100struct{float address;float length; /*已分分区长度,单位为字节*/int flag; /*已分配区表登记栏标志,用"0"表示空栏目*/}used_table[n]; /*已分配区表*/struct{float address; /*空闲区起始地址*/float length; /*空闲区长度,单位为字节*/int flag; /*空闲区表登记栏标志,用"0"表示空栏目,用"1"表示未分配*/}free_table[m];void main( ){int i,a;void allocate(char str,float leg);//分配主存空间函数void reclaim(char str);//回收主存函数float xk;char J;/*空闲分区表初始化:*/free_table[0].address=10240;free_table[0].length=102400;free_table[0].flag=1;for(i=1;i<m;i++)free_table[i].flag=0;/*已分配表初始化:*/for(i=0;i<n;i++)used_table[i].flag=0;while(1){printf("\n选择功能项(0-退出,1-分配主存,2-回收主存,3-显示主存)\n");printf("选择功项(0~3) :");scanf("%d",&a);switch(a){case 0: exit(0); /*a=0程序结束*/case 1: /*a=1分配主存空间*/printf("输入作业名J和作业所需长度xk: ");scanf("%*c%c%f",&J,&xk);allocate(J,xk);/*分配主存空间*/break;case 2: /*a=2回收主存空间*/printf("输入要回收分区的作业名");scanf("%*c%c",&J);reclaim(J);/*回收主存空间*/break;case 3: /*a=3显示主存情况*//*输出空闲区表和已分配表的内容*/printf("输出空闲区表:\n起始地址分区长度标志\n");for(i=0;i<m;i++)printf("%6.0f%9.0f%6d\n",free_table[i].address,free_table[i].length, free_table[i].flag);printf(" 按任意键,输出已分配区表\n");getchar();printf(" 输出已分配区表:\n起始地址分区长度标志\n");for(i=0;i<n;i++)if(used_table[i].flag!=0)printf("%6.0f%9.0f%6c\n",used_table[i].address,used_table[i].lengt h, used_table[i].flag);elseprintf("%6.0f%9.0f%6d\n",used_table[i].address,used_table[i].lengt h, used_table[i].flag);break;default:printf("没有该选项\n");}/*case*/}/*while*/}/*主函数结束*/int uflag;//分配表标志int fflag;//空闲表标志float uend_address;float fend_address;void allocate(char str,float leg){uflag=0;fflag=0;int k,i;float ressize;for(i=0;i<m;i++){if(free_table[i].flag==1 && free_table[i].length>=leg) {fflag=1;break;}}if(fflag==0)printf("没有满足条件的空闲区\n");else{ressize=free_table[i].length-leg;for(k=0;k<n;k++){if(used_table[k].flag==0){if(ressize<minisize)//剩余块过小{used_table[k].length=free_table[i].length;used_table[k].address=free_table[i].address;used_table[k].flag=str;free_table[i].length=0;free_table[i].flag=0;break;}else{used_table[k].address=free_table[i].address+ressize;used_table[k].flag=str;used_table[k].length=leg;free_table[i].length=ressize;break;}}}//for结束}}void reclaim(char str){uflag=0;fflag=0;int k,i;for(k=0;k<n;k++){if(used_table[k].flag==str){uflag=1;break;}}if(uflag==0)printf("\n找不到该作业!\n");else{for(i=0;i<m;i++){uend_address=used_table[k].address+used_table[k].length; fend_address=free_table[i].address+free_table[i].length;if(used_table[k].address==fend_address)//上邻{fflag=1;free_table[i].length=free_table[i].length+used_table[k].length;free_table[i].flag=1;used_table[k].flag=0;used_table[k].length=0;used_table[k].address=0;printf("\n已回收!\n");break;}else{if(free_table[i].address==uend_address)//下邻{fflag=1;free_table[i].address=used_table[k].address;free_table[i].length=free_table[i].length+used_table[k].length;free_table[i].flag=1;used_table[k].flag=0;used_table[k].length=0;used_table[k].address=0;printf("\n已回收!\n");break;}}}//for结束if(fflag==0){i=0;for(i=0;i<m;i++){if(free_table[i].flag==0){free_table[i].address=used_table[k].address;free_table[i].length=used_table[k].length;free_table[i].flag=1;used_table[k].length=0;used_table[k].flag=0;used_table[k].address=0;break;}}printf("\n已回收!\n");}}}11。

实验四操作系统存储管理实验报告

实验四操作系统存储管理实验报告

实验四操作系统存储管理实验报告一、实验目的本次实验的主要目的是深入理解操作系统中存储管理的基本原理和方法,通过实际操作和观察,掌握内存分配与回收、页面置换算法等关键概念,并能够分析和解决存储管理中可能出现的问题。

二、实验环境本次实验在装有 Windows 操作系统的计算机上进行,使用了 Visual Studio 等编程工具和相关的调试环境。

三、实验内容(一)内存分配与回收算法实现1、首次适应算法首次适应算法从内存的起始位置开始查找,找到第一个能够满足需求的空闲分区进行分配。

在实现过程中,我们通过建立一个空闲分区链表来管理内存空间,每次分配时从表头开始查找。

2、最佳适应算法最佳适应算法会选择能够满足需求且大小最小的空闲分区进行分配。

为了实现该算法,在空闲分区链表中,分区按照大小从小到大的顺序排列,这样在查找时能够快速找到最合适的分区。

3、最坏适应算法最坏适应算法则选择最大的空闲分区进行分配。

同样通过对空闲分区链表的排序和查找来实现。

(二)页面置换算法模拟1、先进先出(FIFO)页面置换算法FIFO 算法按照页面进入内存的先后顺序进行置换,即先进入内存的页面先被置换出去。

在模拟过程中,使用一个队列来记录页面的进入顺序。

2、最近最久未使用(LRU)页面置换算法LRU 算法根据页面最近被使用的时间来决定置换顺序,最近最久未使用的页面将被置换。

通过为每个页面设置一个时间戳来记录其最近使用的时间,从而实现置换策略。

3、时钟(Clock)页面置换算法Clock 算法使用一个环形链表来模拟内存中的页面,通过指针的移动和页面的访问标志来决定置换页面。

四、实验步骤(一)内存分配与回收算法的实现步骤1、初始化内存空间,创建空闲分区链表,并为每个分区设置起始地址、大小和状态等信息。

2、对于首次适应算法,从链表表头开始遍历,找到第一个大小满足需求的空闲分区,进行分配,并修改分区的状态和大小。

3、对于最佳适应算法,在遍历链表时,选择大小最接近需求的空闲分区进行分配,并对链表进行相应的调整。

操作系统存储管理动态分区分配及回收算法附源码

操作系统存储管理动态分区分配及回收算法附源码

存储管理动态分区分配及回收算法课程名称:计算机操作系统班级:信1501-2实验者姓名:李琛实验日期:2018年5月20日评分: 教师签名:一、实验目的分区管理就是应用较广泛的一种存储管理技术。

本实验要求用一种结构化高级语言构造分区描述器,编制动态分区分配算法与回收算法模拟程序,并讨论不同分配算法的特点。

二、实验要求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;然后,提示用户使用哪种分配算法,再提示就是分配还就是回收;分配时要求输入申请区的大小,回收时要求输入释放区的首址与大小。

实验代码Main、cpp#include<stdio、h>#include<stdlib、h>#include<string、h>#include<iostream>using namespace std;#define MAX_SIZE 32767typedef struct node{int id;int adr;int size;struct node *next;}Node;Node *head1, *head2, *back1, *back2, *assign;int request;int check(int add, int siz, char c){Node *p, *head;int check = 1;if (add<0 || siz<0)check = 0;/*地址与大小不能为负*/if (c == 'f' || c == 'F')head = head1;elsehead = head2;p = head->next;while ((p != NULL) && check)if (((add<p->adr) && (add + siz>p->adr)) || ((add >= p->adr) && (add<p->adr + p->size))) check = 0;elsep = p->next;if (check == 0)printf("\t输入释放区地址或大小有错误!!!\n");return check;}void init(){Node *p;head1 = (Node*)malloc(sizeof(Node));head2 = (Node*)malloc(sizeof(Node));p = (Node*)malloc(sizeof(Node));head1->next = p;head2->next = p;p->size = MAX_SIZE;p->adr = 0;p->next = NULL;p->id = 0;}Node* assignment1(int num, int req){Node *before, *after, *ass;ass = (Node*)malloc(sizeof(Node));before = head1;after = head1->next;ass->id = num;ass->size = req;while (after->size<req){before = before->next;after = after->next;}if (after == NULL){ass->adr = -1;}else{if (after->size == req){before->next = after->next;ass->adr = after->adr;}else{after->size -= req;ass->adr = after->adr;after->adr += req;}}return ass;}void acceptment1(int address, int siz, int rd) {Node *before, *after;int insert = 0;back1 = (Node*)malloc(sizeof(Node));before = head1;after = head1->next;back1->adr = address;back1->size = siz;back1->id = rd;back1->next = NULL;while (!insert&&after){//将要被回收的分区插入空闲区(按首址大小从小到大插入)if ((after == NULL) || ((back1->adr <= after->adr) && (back1->adr >= before->adr))){before->next = back1;back1->next = after;insert = 1;}else{before = before->next;after = after->next;}}if (insert){if (back1->adr == before->adr + before->size){//与前边分区合并before->size += back1->size;before->next = back1->next;free(back1);}else if (after&&back1->adr + back1->size == after->adr){//与后边分区合并back1->size += after->size;back1->next = after->next;back1->id = after->id;free(after);after = back1;}printf("\t首先分配算法回收内存成功!\n");}elseprintf("\t首先分配算法回收内存失败!\n");}Node* assignment2(int num, int req){Node *before, *after, *ass, *q;ass = (Node*)malloc(sizeof(Node));q = (Node*)malloc(sizeof(Node));before = head2;after = head2->next;ass->id = num;ass->size = req;while (after->size<req){before = before->next;after = after->next;}if (after == NULL){ass->adr = -1;}else{if (after->size == req){before->next = after->next;ass->adr = after->adr;}else{q = after;before->next = after->next;ass->adr = q->adr;q->size -= req;q->adr += req;before = head2;after = head2->next;if (after == NULL){before->next = q;q->next = NULL;}else{while ((after->size)<(q->size)){before = before->next;after = after->next;}before->next = q;q->next = after;}}}return (ass);}void acceptment2(int address, int siz, int rd){Node *before, *after;int insert = 0;back2 = (Node*)malloc(sizeof(Node));before = head2;after = head2->next;back2->adr = address;back2->size = siz;back2->id = rd;back2->next = NULL;if (head2->next == NULL){//空闲队列为空head2->next = back2;head2->size = back2->size;}else{//空闲队列不为空while (after){if (back2->adr == after->adr + after->size){//与前边空闲分区合并before->next = after->next;after->size += back2->size;back2 = after;}else{before = before->next;after = after->next;}}before = head2;after = head2->next;while (after){if (after->adr == back2->adr + back2->size){//与后边空闲区合并before->next = after->next;back2->size += after->size;}else{before = before->next;after = after->next;}}before = head2;after = head2->next;while (!insert){//将被回收的块插入到恰当的位置(按分区大小从小到大)if (after == NULL || ((after->size>back2->size) && (before->size<back2->size))){before->next = back2;back2->next = after;insert = 1;break;}else{before = before->next;after = after->next;}}}if (insert)printf("\t最佳适应算法回收内存成功!\n");elseprintf("\t最佳适应算法回收内存失败!!\n");}void print(char choice)//输出空闲区队列信息{Node *p;if (choice == 'f' || choice == 'F')p = head1->next;elsep = head2->next;if (p){printf("\n空闲区队列的情况为:\n");printf("\t编号\t首址\t终址\t大小\n");while (p){printf("\t%d\t%d\t%d\t%d\n", p->id, p->adr, p->adr + p->size - 1, p->size);p = p->next;}}}void menu()//菜单及主要过程{char chose;int ch, num=0, r, add, rd;while (1){system("cls");printf("-------存储管理动态分区分配及回收算法-------\n");printf(" F 最先适应算法\n");printf(" B 最佳适应算法\n");printf(" E 退出程序\n");printf("----------------------------------------------\n");printf("请选择算法:");cin >> chose;//scanf("%c", &chose);if (chose == 'e' || chose == 'E')exit(0);else{system("cls");while (1){if (chose == 'f' || chose == 'F')printf("最先适应算法:\n");if (chose == 'b' || chose == 'B')printf("最佳适应算法:\n");printf("----------------------------------------------\n");printf(" 1 分配内存\n");printf(" 2 回收内存\n");printf(" 3 查瞧内存\n");printf(" 4 返回\n");printf("----------------------------------------------\n\n");printf("请选择:");scanf("%d", &ch);fflush(stdin);switch (ch){case 1:printf("输入申请的分区大小:"); scanf("%d", &r);if (chose == 'f' || chose == 'F')assign = assignment1(num, r);elseassign = assignment2(num, r);if (assign->adr == -1){printf("分配内存失败!\n");}elseprintf("分配成功!分配的内存的首址为:%d\n", assign->adr);break;case 2:printf("输入释放的内存的首址:"); scanf("%d", &add);printf("输入释放的内存的大小:"); scanf("%d", &r);printf("输入释放的内存的编号:"); scanf("%d", &rd);if (check(add, r, chose)){if (chose == 'f' || chose == 'F')acceptment1(add, r, rd);elseacceptment2(add, r, rd);}break;case 3:print(chose); break;case 4:menu(); break;}}}}}void main()//主函数{init();menu();}四、实验结果操作系统存储管理动态分区分配及回收算法附源码五、实验总结通过这次实验我练习了存储管理动态分区分配及回收算法,对操作系统中动态可变分区存储管理有了更深刻的了解。

操作系统实验四报告-主存空间分配和回收(含源码)

操作系统实验四报告-主存空间分配和回收(含源码)

操作系统实验四报告-主存空间分配和回收(含源码)计算机学院计算机科学与技术专业班学号姓名教师评定_________________实验题目主存空间的分配和回收一、实验目的熟悉主存的分配与回收。

理解在不同的存储管理方式下,如何实现主存空间的分配与回收。

掌握动态分区分配方式中的数据结构和分配算法及动态分区存储管理方式及其实现过程。

二、实验内容和要求主存的分配和回收的实现是与主存储器的管理方式有关的。

所谓分配,就是解决多道作业或多进程如何共享主存空间的问题。

所谓回收,就是当作业运行完成时将作业或进程所占的主存空间归还给系统。

可变分区管理是指在处理作业过程中建立分区,使分区大小正好适合作业的需求,并且分区个数是可以调整的。

当要装入一个作业时,根据作业需要的主存量查看是否有足够的空闲空间,若有,则按需要量分割一个分区分配给该作业;若无,则作业不能装入,作业等待。

随着作业的装入、完成,主存空间被分成许多大大小小的分区,有的分区被作业占用,而有的分区是空闲的。

实验要求使用可变分区存储管理方式,分区分配中所用的数据结构采用空闲分区表和空闲分区链来进行,分区分配中所用的算法采用首次适应算法、最佳适应算法、最差适应算法三种算法来实现主存的分配与回收。

同时,要求设计一个实用友好的用户界面,并显示分配与回收的过程。

同时要求设计一个实用友好的用户界面,并显示分配与回收的过程。

三、实验主要仪器设备和材料实验环境硬件环境:IBM-PC或兼容机软件环境:VC++ 6.0四、实验原理及设计分析某系统采用可变分区存储管理,在系统运行当然开始,假设初始状态下,可用的内存空间为640KB,存储器区被分为操作系统分区(40KB)和可给用户的空间区(600KB)。

(作业1 申请130KB、作业2 申请60KB、作业3 申请100KB 、作业2 释放 60KB 、作业4 申请 200KB、作业3释放100KB、作业1 释放130KB 、作业5申请140KB 、作业6申请60KB 、作业7申请50KB)当作业1进入内存后,分给作业1(130KB),随着作业1、2、3的进入,分别分配60KB、100KB,经过一段时间的运行后,作业2运行完毕,释放所占内存。

主存空间的分配与回收实验报告

主存空间的分配与回收实验报告

主存空间的分配与回收实验报告附录:源代码#include<stdio.h>#include<stdlib.h>#define OK 1 //完成#define ERROR 0 //出错typedef int Status;typedef struct free_table//定义一个空闲区说明表结构{int num; //分区序号long address; //起始地址long length; //分区大小int state; //分区状态}ElemType;typedef struct Node// 线性表的双向链表存储结构{ElemType data;struct Node *prior; //前趋指针struct Node *next; //后继指针}Node,*LinkList;LinkList first; //头结点LinkList end; //尾结点int flag;//记录要删除的分区序号Status Initblock()//开创带头结点的内存空间链表{first=(LinkList)malloc(sizeof(Node)); end=(LinkList)malloc(sizeof(Node)); first->prior=NULL;first->next=end;end->prior=first;end->next=NULL;end->data.num=1;end->data.address=40;end->data.length=600;end->data.state=0;return OK;}void sort()//分区序号重新排序{Node *p=first->next,*q;q=p->next;for(;p!=NULL;p=p->next){f or(q=p->next;q;q=q->next){if(p->data.num>=q->data.num){q->data.num+=1;}}}}//显示主存分配情况void show(){ int flag=0;//用来记录分区序号Node *p=first;p->data.num=0;p->data.address=0;p->data.length=40;p->data.state=1;sort();printf("\n\t\t》主存空间分配情况《\n");printf("********************************** ************************\n\n");printf("分区序号\t起始地址\t分区大小\t分区状态\n\n");while(p){printf("%d\t\t%d\t\t%d",p->data.num,p->data. address,p->data.length);if(p->data.state==0) printf("\t\t空闲\n\n");else printf("\t\t已分配\n\n");p=p->next;}printf("********************************** ************************\n\n");}//首次适应算法Status First_fit(int request){//为申请作业开辟新空间且初始化Node *p=first->next;LinkListtemp=(LinkList)malloc(sizeof(Node));temp->data.length=request;temp->data.state=1;p->data.num=1;while(p){if((p->data.state==0)&&(p->data.length==reque st)){//有大小恰好合适的空闲块p->data.state=1;return OK;break;}else if((p->data.state==0) && (p->data.length>request)){//有空闲块能满足需求且有剩余temp->prior=p->prior;temp->next=p;temp->data.address=p->data.address;temp->data.num=p->data.num;p->prior->next=temp;p->prior=temp;p->data.address=temp->data.address+temp->da ta.length;p->data.length-=request;p->data.num+=1;return OK;break;}p=p->next;}return ERROR;}//最佳适应算法Status Best_fit(int request){int ch; //记录最小剩余空间Node *p=first;Node *q=NULL; //记录最佳插入位置LinkListtemp=(LinkList)malloc(sizeof(Node));temp->data.length=request;temp->data.state=1;p->data.num=1;while(p) //初始化最小空间和最佳位置{if((p->data.state==0) && (p->data.length>=request) ){if(q==NULL){q=p;ch=p->data.length-request;}else if(q->data.length > p->data.length){q=p;ch=p->data.length-request;}}p=p->next;}if(q==NULL) return ERROR;//没有找到空闲块else if(q->data.length==request){q->data.state=1;return OK;}else{temp->prior=q->prior;temp->next=q;temp->data.address=q->data.address;temp->data.num=q->data.num;q->prior->next=temp;q->prior=temp;q->data.address+=request;q->data.length=ch;q->data.num+=1;return OK;}return OK;}//最差适应算法Status Worst_fit(int request){int ch; //记录最大剩余空间Node *p=first->next;Node *q=NULL; //记录最佳插入位置LinkListtemp=(LinkList)malloc(sizeof(Node));temp->data.length=request;temp->data.state=1;p->data.num=1;while(p) //初始化最大空间和最佳位置{if(p->data.state==0 && (p->data.length>=request) ){if(q==NULL){q=p;ch=p->data.length-request;}else if(q->data.length <p->data.length){q=p;ch=p->data.length-request;}}p=p->next;}if(q==NULL) return ERROR;//没有找到空闲块else if(q->data.length==request){q->data.length=1;return OK;}else{temp->prior=q->prior;temp->next=q;temp->data.address=q->data.address;temp->data.num=q->data.num;q->prior->next=temp;q->prior=temp;q->data.address+=request;q->data.length=ch;q->data.num+=1;return OK;}return OK;}//分配主存Status allocation(int a){int request;//申请内存大小printf("请输入申请分配的主存大小(单位:KB):");scanf("%d",&request);if(request<0 ||request==0){printf("分配大小不合适,请重试!");return ERROR;}switch(a)case 1: //默认首次适应算法if(First_fit(request)==OK)printf("\t****分配成功!****");else printf("\t****内存不足,分配失败!****");return OK;break;case 2: //选择最佳适应算法if(Best_fit(request)==OK)printf("\t****分配成功!****");else printf("\t****内存不足,分配失败!****");return OK;break;case 3: //选择最差适应算法if(Worst_fit(request)==OK) printf("\t****分配成功!****");else printf("\t****内存不足,分配失败!****");return OK;break;}Status deal1(Node *p)//处理回收空间{Node *q=first;for(;q!=NULL;q=q->next){if(q==p){if(q->prior->data.state==0&&q->next->data.s tate!=0){q->prior->data.length+=q->data.length;q->prior->next=q->next;q->next->prior=q->prior;q=q->prior;q->data.state=0;q->data.num=flag-1;}if(q->prior->data.state!=0&&q->next->data.stat e==0){q->data.length+=q->next->data.length;q->next=q->next->next;q->next->next->prior=q;q->data.state=0;q->data.num=flag;}if(q->prior->data.state==0&&q->next->data.sta te==0){q->prior->data.length+=q->data.length;q->prior->next=q->next;q->next->prior=q->prior;q=q->prior;q->data.state=0;q->data.num=flag-1;}if(q->prior->data.state!=0&&q->next->data.state!=0){q->data.state=0;}}}return OK;}Status deal2(Node *p)//处理回收空间{Node *q=first;for(;q!=NULL;q=q->next){if(q==p){if(q->prior->data.state==0&&q->next->data.s tate!=0){q->prior->data.length+=q->data.length;q->prior->next=q->next;q->next->prior=q->prior;q=p->prior;q->data.state=0;q->data.num=flag-1;}if(q->prior->data.state!=0&&q->next->data.stat e==0){q->data.state=0;}if(q->prior->data.state==0&&q->next->data.sta te==0){q->prior->data.length+=q->data.length;q->prior->next=q->next;q->next->prior=q->prior;q=q->prior;q->data.state=0;q->data.num=flag-1;}if(q->prior->data.state!=0&&q->next->data.stat e!=0){q->data.state=0;}}}return OK;}//主存回收Status recovery(int flag){Node *p=first;for(;p!=NULL;p=p->next){if(p->data.num==flag){if(p->prior==first){if(p->next!=end)//当前P指向的下一个不是最后一个时{if(p->next->data.state==0) //与后面的空闲块相连{p->data.length+=p->next->data.length;p->next->next->prior=p;p->next=p->next->next;p->data.state=0;p->data.num=flag;}else p->data.state=0;}if(p->next==end)//当前P指向的下一个是最后一个时{p->data.state=0;}}//结束if(p->prior==block_first)的情况else if(p->prior!=first){if(p->next!=end){deal1(p);}else{deal2(p);}}//结束if(p->prior!=block_first)的情况}//结束if(p->data.num==flag)的情况}printf("\t****回收成功****");return OK;}//主函数void main(){int i; //操作选择标记int a;//算法选择标记printf("**********************************************************\n");printf("\t\t用以下三种方法实现主存空间的分配\n");printf("\t(1)首次适应算法\t(2)最佳适应算法\t(3)最差适应算法\n");printf("******************************** **************************\n");printf("\n");printf("请输入所使用的内存分配算法:");scanf("%d",&a);while(a<1||a>3){printf("输入错误,请重新输入所使用的内存分配算法:\n");scanf("%d",&a);}switch(a){case 1:printf("\n\t****使用首次适应算法:****\n");break;case 2:printf("\n\t****使用最佳适应算法:****\n");break;case 3:printf("\n\t****使用最坏适应算法:****\n");break;}Initblock(); //开创空间表while(1){show();printf("\t1: 分配内存\t2: 回收内存\t0: 退出\n");printf("请输入您的操作:");scanf("%d",&i);if(i==1)allocation(a); // 分配内存else if(i==2) // 内存回收{printf("请输入您要释放的分区号:");scanf("%d",&flag);recovery(flag);}else if(i==0){printf("\n退出程序\n");break; //退出}else //输入操作有误{printf("输入有误,请重试!");continue;}}}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

计算机学院计算机科学与技术专业班学号姓名教师评定_________________ 实验题目主存空间的分配和回收一、实验目的熟悉主存的分配与回收。

理解在不同的存储管理方式下,如何实现主存空间的分配与回收。

掌握动态分区分配方式中的数据结构和分配算法及动态分区存储管理方式及其实现过程。

二、实验内容和要求主存的分配和回收的实现是与主存储器的管理方式有关的。

所谓分配,就是解决多道作业或多进程如何共享主存空间的问题。

所谓回收,就是当作业运行完成时将作业或进程所占的主存空间归还给系统。

可变分区管理是指在处理作业过程中建立分区,使分区大小正好适合作业的需求,并且分区个数是可以调整的。

当要装入一个作业时,根据作业需要的主存量查看是否有足够的空闲空间,若有,则按需要量分割一个分区分配给该作业;若无,则作业不能装入,作业等待。

随着作业的装入、完成,主存空间被分成许多大大小小的分区,有的分区被作业占用,而有的分区是空闲的。

实验要求使用可变分区存储管理方式,分区分配中所用的数据结构采用空闲分区表和空闲分区链来进行,分区分配中所用的算法采用首次适应算法、最佳适应算法、最差适应算法三种算法来实现主存的分配与回收。

同时,要求设计一个实用友好的用户界面,并显示分配与回收的过程。

同时要求设计一个实用友好的用户界面,并显示分配与回收的过程。

三、实验主要仪器设备和材料实验环境硬件环境:IBM-PC或兼容机软件环境:VC++ 6.0四、实验原理及设计分析某系统采用可变分区存储管理,在系统运行当然开始,假设初始状态下,可用的内存空间为640KB,存储器区被分为操作系统分区(40KB)和可给用户的空间区(600KB)。

(作业1 申请130KB、作业2 申请60KB、作业3 申请100KB 、作业2 释放 60KB 、作业4 申请 200KB、作业3释放100KB、作业1 释放130KB 、作业5申请140KB 、作业6申请60KB 、作业7申请50KB)当作业1进入内存后,分给作业1(130KB),随着作业1、2、3的进入,分别分配60KB、100KB,经过一段时间的运行后,作业2运行完毕,释放所占内存。

此时,作业4进入系统,要求分配200KB内存。

作业3、1运行完毕,释放所占内存。

此时又有作业5申请140KB,作业6申请60KB,作业7申请50KB。

为它们进行主存分配和回收。

1、采用可变分区存储管理,使用空闲分区链实现主存分配和回收。

空闲分区链:使用链指针把所有的空闲分区链成一条链,为了实现对空闲分区的分配和链接,在每个分区的起始部分设置状态位、分区的大小和链接各个分区的前向指针,由状态位指示该分区是否分配出去了;同时,在分区尾部还设置有一后向指针,用来链接后面的分区;分区中间部分是用来存放作业的空闲内存空间,当该分区分配出去后,状态位就由“0”置为“1”。

设置一个内存空闲分区链,内存空间分区通过空闲分区链来管理,在进行内存分配时,系统优先使用空闲低端的空间。

设计一个空闲分区说明链,设计一个某时刻主存空间占用情况表,作为主存当前使用基础。

初始化空间区和已分配区说明链的值,设计作业申请队列以及作业完成后释放顺序,实现主存的分配和回收。

要求每次分配和回收后显示出空闲内存分区链的情况。

把空闲区说明链的变化情况以及各作业的申请、释放情况显示打印出来。

2.采用可变分区存储管理,分别采用首次适应算法、最佳适应算法和最坏适应算法实现主存分配和回收。

3、主存空间分配(1)首次适应算法在该算法中,把主存中所有空闲区按其起始地址递增的次序排列。

在为作业分配存储空间时,从上次找到的空闲分区的下一个空闲分区开始查找,直到找到第一个能满足要求的空闲区,从中划出与请求的大小相等的存储空间分配给作业,余下的空闲区仍留在空闲区链中。

(2)最佳适应算法在该算法中,把主存中所有空闲区按其起始地址递增的次序排列。

在为作业分配存储空间时,从上次找到的空闲分区的下一个空闲分区开始查找,直到找到一个能满足要求的空闲区且该空闲区的大小比其他满足要求的空闲区都小,从中划出与请求的大小相等的存储空间分配给作业,余下的空闲区仍留在空闲区链中(3)最坏适应算法在该算法中,把主存中所有空闲区按其起始地址递增的次序排列。

在为作业分配存储空间时,从上次找到的空闲分区的下一个空闲分区开始查找,直到找到一个能满足要求的空闲区且该空闲区的大小比其他满足要求的空闲区都大,从中划出与请求的大小相等的存储空间分配给作业,余下的空闲区仍留在空闲区链中。

4、主存空间回收当一个作业执行完成撤离时,作业所占的分区应该归还给系统。

归还的分区如果与其它空闲区相邻,则应合成一个较大的空闲区,登记在空闲区说明链中,此时,相邻空闲区的合并问题,要求考虑四种情况:(1)释放区下邻空闲区(低地址邻接)(2)释放区上邻空闲区(高地址邻接)(3)释放区上下都与空闲区邻接(4)释放区上下邻都与空闲区不邻接五、程序流程图main函数里的流程图分配空间里的流程图回收空间里的流程图六、相关数据结构及关键函数说明本程序采用了一个struct free_table数据结构,里面包含分区序号(num)、起始地址(address)、分区长度(length)和分区状态(state)。

还用了线性表的双性链表存储结构(struct Node),里面包含前区指针(prior)和后继指针(next)。

一开始定义一条(含有first和end)的链,用开始指针和尾指针开创空间链表。

然后分别按三种算法进行分配和回收。

在该程序中关键函数有,sort()、allocation()、recovery()、和First_fit()、Best_fit ()、Worst_fit();其中sort()函数是用来整理分区序号的,如在删序号3时,她与前面序号2相连在一起了,然后序号2中的长度总满足申请的内存大小,就会在序号2中分配,然后序号在2的基础上加1,一直加,加到与原本序号3的下一个序号也就是4相等,这时sort()就开始有明显的工作了;allocation()是分配空间的,也是过渡到三个算法中的,当三个算法中满足或者不满足分配请求,都会又返回值给allocation();recovery()是用来回收内存的,里面包含了四种情况相连结果,即释放区上与空闲区邻接、释放区下与空闲区邻接、释放区上下都与空闲区邻接、释放区上下都与空闲区不邻接这四种情况的结果。

七、源代码#include<stdio.h>#include<stdlib.h>#define OK 1 //完成#define ERROR 0 //出错typedef int Status;typedef struct free_table//定义一个空闲区说明表结构{int num; //分区序号long address; //起始地址long length; //分区大小int state; //分区状态}ElemType;typedef struct Node// 线性表的双向链表存储结构{ElemType data;struct Node *prior; //前趋指针struct Node *next; //后继指针}Node,*LinkList;LinkList first; //头结点LinkList end; //尾结点int flag;//记录要删除的分区序号Status Initblock()//开创带头结点的内存空间链表{first=(LinkList)malloc(sizeof(Node));end=(LinkList)malloc(sizeof(Node));first->prior=NULL;first->next=end;end->prior=first;end->next=NULL;end->data.num=1;end->data.address=40;end->data.length=600;end->data.state=0;return OK;}void sort()//分区序号重新排序{Node *p=first->next,*q;q=p->next;for(;p!=NULL;p=p->next){for(q=p->next;q;q=q->next){if(p->data.num>=q->data.num){q->data.num+=1;}}}}//显示主存分配情况void show(){ int flag=0;//用来记录分区序号Node *p=first;p->data.num=0;p->data.address=0;p->data.length=40;p->data.state=1;sort();printf("\n\t\t》主存空间分配情况《\n");printf("**********************************************************\n\n");printf("分区序号\t起始地址\t分区大小\t分区状态\n\n");while(p){printf("%d\t\t%d\t\t%d",p->data.num,p->data.address,p->data.length);if(p->data.state==0) printf("\t\t空闲\n\n");else printf("\t\t已分配\n\n");p=p->next;}printf("**********************************************************\n\n"); }//首次适应算法Status First_fit(int request){//为申请作业开辟新空间且初始化Node *p=first->next;LinkList temp=(LinkList)malloc(sizeof(Node));temp->data.length=request;temp->data.state=1;p->data.num=1;while(p){if((p->data.state==0)&&(p->data.length==request)){//有大小恰好合适的空闲块p->data.state=1;return OK;break;}else if((p->data.state==0) && (p->data.length>request)){//有空闲块能满足需求且有剩余temp->prior=p->prior;temp->next=p;temp->data.address=p->data.address;temp->data.num=p->data.num;p->prior->next=temp;p->prior=temp;p->data.address=temp->data.address+temp->data.length;p->data.length-=request;p->data.num+=1;return OK;break;}p=p->next;}return ERROR;}//最佳适应算法Status Best_fit(int request){int ch; //记录最小剩余空间Node *p=first;Node *q=NULL; //记录最佳插入位置LinkList temp=(LinkList)malloc(sizeof(Node));temp->data.length=request;temp->data.state=1;p->data.num=1;while(p) //初始化最小空间和最佳位置{if((p->data.state==0) && (p->data.length>=request) ){if(q==NULL){q=p;ch=p->data.length-request;}else if(q->data.length > p->data.length){q=p;ch=p->data.length-request;}}p=p->next;}if(q==NULL) return ERROR;//没有找到空闲块else if(q->data.length==request){q->data.state=1;return OK;}else{temp->prior=q->prior;temp->next=q;temp->data.address=q->data.address;temp->data.num=q->data.num;q->prior->next=temp;q->prior=temp;q->data.address+=request;q->data.length=ch;q->data.num+=1;return OK;}return OK;}//最差适应算法Status Worst_fit(int request){int ch; //记录最大剩余空间Node *p=first->next;Node *q=NULL; //记录最佳插入位置LinkList temp=(LinkList)malloc(sizeof(Node));temp->data.length=request;temp->data.state=1;p->data.num=1;while(p) //初始化最大空间和最佳位置{if(p->data.state==0 && (p->data.length>=request) ){if(q==NULL){q=p;ch=p->data.length-request;}else if(q->data.length < p->data.length){q=p;ch=p->data.length-request;}}p=p->next;}if(q==NULL) return ERROR;//没有找到空闲块else if(q->data.length==request){q->data.length=1;return OK;}else{temp->prior=q->prior;temp->next=q;temp->data.address=q->data.address;temp->data.num=q->data.num;q->prior->next=temp;q->prior=temp;q->data.address+=request;q->data.length=ch;q->data.num+=1;return OK;}return OK;}//分配主存Status allocation(int a){int request;//申请内存大小printf("请输入申请分配的主存大小(单位:KB):");scanf("%d",&request);if(request<0 ||request==0){printf("分配大小不合适,请重试!");return ERROR;}switch(a){case 1: //默认首次适应算法if(First_fit(request)==OK) printf("\t****分配成功!****");else printf("\t****内存不足,分配失败!****");return OK;break;case 2: //选择最佳适应算法if(Best_fit(request)==OK) printf("\t****分配成功!****");else printf("\t****内存不足,分配失败!****");return OK;break;case 3: //选择最差适应算法if(Worst_fit(request)==OK) printf("\t****分配成功!****");else printf("\t****内存不足,分配失败!****");return OK;break;}}Status deal1(Node *p)//处理回收空间{Node *q=first;for(;q!=NULL;q=q->next){if(q==p){if(q->prior->data.state==0&&q->next->data.state!=0){q->prior->data.length+=q->data.length;q->prior->next=q->next;q->next->prior=q->prior;q=q->prior;q->data.state=0;q->data.num=flag-1;}if(q->prior->data.state!=0&&q->next->data.state==0){q->data.length+=q->next->data.length;q->next=q->next->next;q->next->next->prior=q;q->data.state=0;q->data.num=flag;}if(q->prior->data.state==0&&q->next->data.state==0){q->prior->data.length+=q->data.length;q->prior->next=q->next;q->next->prior=q->prior;q=q->prior;q->data.state=0;q->data.num=flag-1;}if(q->prior->data.state!=0&&q->next->data.state!=0){q->data.state=0;}}}return OK;}Status deal2(Node *p)//处理回收空间{Node *q=first;for(;q!=NULL;q=q->next){if(q==p){if(q->prior->data.state==0&&q->next->data.state!=0){q->prior->data.length+=q->data.length;q->prior->next=q->next;q->next->prior=q->prior;q=p->prior;q->data.state=0;q->data.num=flag-1;}if(q->prior->data.state!=0&&q->next->data.state==0){q->data.state=0;}if(q->prior->data.state==0&&q->next->data.state==0){q->prior->data.length+=q->data.length;q->prior->next=q->next;q->next->prior=q->prior;q=q->prior;q->data.state=0;q->data.num=flag-1;}if(q->prior->data.state!=0&&q->next->data.state!=0){q->data.state=0;}}}return OK;}//主存回收Status recovery(int flag){Node *p=first;for(;p!=NULL;p=p->next){if(p->data.num==flag){if(p->prior==first){if(p->next!=end)//当前P指向的下一个不是最后一个时{if(p->next->data.state==0) //与后面的空闲块相连{p->data.length+=p->next->data.length;p->next->next->prior=p;p->next=p->next->next;p->data.state=0;p->data.num=flag;}else p->data.state=0;}if(p->next==end)//当前P指向的下一个是最后一个时{p->data.state=0;}}//结束if(p->prior==block_first)的情况else if(p->prior!=first){if(p->next!=end){deal1(p);}else{deal2(p);}}//结束if(p->prior!=block_first)的情况}//结束if(p->data.num==flag)的情况}printf("\t****回收成功****");return OK;}//主函数void main(){int i; //操作选择标记int a;//算法选择标记printf("**********************************************************\n");printf("\t\t用以下三种方法实现主存空间的分配\n");printf("\t(1)首次适应算法\t(2)最佳适应算法\t(3)最差适应算法\n");printf("**********************************************************\n");printf("\n");printf("请输入所使用的内存分配算法:");scanf("%d",&a);while(a<1||a>3){printf("输入错误,请重新输入所使用的内存分配算法:\n");scanf("%d",&a);}switch(a){case 1:printf("\n\t****使用首次适应算法:****\n");break;case 2:printf("\n\t****使用最佳适应算法:****\n");break;case 3:printf("\n\t****使用最坏适应算法:****\n");break;}Initblock(); //开创空间表while(1){show();printf("\t1: 分配内存\t2: 回收内存\t0: 退出\n");printf("请输入您的操作:");scanf("%d",&i);if(i==1)allocation(a); // 分配内存else if(i==2) // 内存回收{printf("请输入您要释放的分区号:");scanf("%d",&flag);recovery(flag);}else if(i==0){printf("\n退出程序\n");break; //退出}else //输入操作有误{printf("输入有误,请重试!");continue;}}}八、执行结果和结果分析初始化首次适应算法:当作业1、2、3顺利分配内存空间后:回收序号2里面的内存:分配作业4:回收序号3里面的内存(与上邻序号2相连了)回收序号1里的内存(与下邻序号2相连了)继续分配(会发现总是按顺序查找满足要求的第一个空闲块,一旦发现就会分配):初始化最佳适应算法:继续分配(会发现总是查找满足要求的空闲块且其比其他空闲块长度小,一旦发现就会分配):初始化最坏适应算法:继续分配(会发现总是查找满足要求的空闲块且其比其他空闲块长度小,一旦发现就会分配):九、所遇困难的解决以及心得体会本实验我采取用一条链表同时表示空闲分区链和主存空间占用情况,因为主存总大小是固定的,把空闲分区链所表示的区域从总的内存里去除就是被占用的空间的大小,这个实验还是比较简单的,但在执行过程中还是遇到了很多问题,如在回收空间的函数中,因为要考虑到四种情况,我一开始的想法是这样的:让p指向链表开头,一直等找到p所指向的分区序号等于要删除的分区序号,然后开始执行,当p->prior不是链首first时要考虑p->next是不是链尾end,然后继续考虑p的前向指针和后向指针得状态是否为空闲;等考虑完p->prior 不是链首了,就进行考虑p->prior是链首的问题,然后又进行了考虑p->next是不是链尾end,然后继续考虑p的前向指针和后向指针得状态是否为空闲;等考虑完了p->prior的问题又进行考虑p->next的问题,一直这样重复了,我都不知道,当时超烦的,后来静下心重新检查自己写得程序,才知道自己写得这个函数好凌乱。

相关文档
最新文档