实验四主存空间的分配和回收
1. 目的和要求
1.1. 实验目的
用高级语言完成一个主存空间的分配和回收程序,以加深对动态分区分配方式及其算法的理解。
1.2. 实验要求
采用连续分配方式之动态分区分配存储管理,使用首次适应算法、循环首次适应算法、最佳适应算法和最坏适应算法4种算法完成设计。
(1)**设计一个作业申请队列以及作业完成后的释放顺序,实现主存的分配和回收。采用分区说明表进行。
(2)或在程序运行过程,由用户指定申请与释放。
(3)设计一个空闲区说明表,以保存某时刻主存空间占用情况。
把空闲区说明表的变化情况以及各作业的申请、释放情况显示。
2. 实验内容
根据指定的实验课题,完成设计、编码和调试工作,完成实验报告。
3. 实验环境
可以选用Visual C++作为开发环境。也可以选用Windows下的VB,CB或其他可视化环境,利用各种控件较为方便。自主选择实验环境。
4. 参考数据结构:
#include<stdio.h>
#include<conio.h>
#include<string.h>
#define MAX 24
struct partition{
char pn[10];
int begin;
int size;
int end; ////////
char status; //////////
};
typedef struct partition PART;
#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(" 》主存空间分配情况《 "); printf("********************************************************** "); printf("分区序号 起始地址 分区大小 分区状态 "); while(p) { printf("%d %d %d",p->data.num,p->data.address,p->data.length); if(p->data.state==0) printf(" 空闲 "); else printf(" 已分配 "); p=p->next; } printf("********************************************************** "); } //首次适应算法 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(" ****分配成功!****"); else printf(" ****内存不足,分配失败!****"); return OK; break; case 2: //选择最佳适应算法 if(Best_fit(request)==OK) printf(" ****分配成功!****"); else printf(" ****内存不足,分配失败!****"); return OK; break; case 3: //选择最差适应算法 if(Worst_fit(request)==OK) printf(" ****分配成功!****"); else printf(" ****内存不足,分配失败!****"); 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(" ****回收成功****"); return OK; } //主函数 void main() { int i; //操作选择标记 int a;//算法选择标记 printf("********************************************************** "); printf(" 用以下三种方法实现主存空间的分配 "); printf(" (1)首次适应算法 (2)最佳适应算法 (3)最差适应算法 "); printf("********************************************************** "); printf(" "); printf("请输入所使用的内存分配算法:"); scanf("%d",&a); while(a<1||a>3) { printf("输入错误,请重新输入所使用的内存分配算法: "); scanf("%d",&a); } switch(a) { case 1: printf(" ****使用首次适应算法:**** "); break; case 2: printf(" ****使用最佳适应算法:**** "); break; case 3: printf(" ****使用最坏适应算法:**** "); break; } Initblock(); //开创空间表 while(1) { show(); printf(" 1: 分配内存 2: 回收内存 0: 退出 "); printf("请输入您的操作:"); scanf("%d",&i); if(i==1) allocation(a); // 分配内存 else if(i==2) // 内存回收 { printf("请输入您要释放的分区号:"); scanf("%d",&flag); recovery(flag); } else if(i==0) { printf(" 退出程序 "); break; //退出 } else //输入操作有误 { printf("输入有误,请重试!"); continue; } } }