【操作系统】实验四 主存空间的分配和回收
1. 实验目的
用高级语言完成一个主存空间的分配和回收程序,以加深对动态分区分配方式及其算法的理解。
2.实验要求
采用连续分配方式之动态分区分配存储管理,使用首次适应算法、循环首次适应算法、最佳适应算法和最坏适应算法4种算法完成设计(任选两种算法)。
(1)设计一个作业申请队列以及作业完成后的释放顺序,实现主存的分配和回收。采用分区说明表进行。
(2)或在程序运行过程,由用户指定申请与释放。
(3)设计一个空闲区说明表,以保存某时刻主存空间占用情况。把空闲区说明表的变化情况以及各作业的申请、释放情况显示。
二、实验内容
编写并调试一个模拟的内存分配与回收程序,使用首次适应算法、循环首次适应算法对内存空间的分配与回收。
三、实验方法、步骤及结果测试
1. 源程序名:a.cpp
可执行程序名:a.exe
2. 原理分析
(1)编写该程序首先要给定一个一定空间大小的内存,即申请空闲区空间最大值,并且要定义空间的各分区的作业标号、分区起始地址、分区长度,单位为字节、分区表的状态位、前向指针、后向指针、已分配分区表、空闲分区等。
(2)通过定义空间分区后,还要定义空间分区链表并对其进行初始化,对空闲分区和已分配分区进行链表访问,对于空闲分区可以分配给新进来的进程使用,对于已分配的分区,则等进程执行结束后在回收空间,恢复空闲区。通过链表的访问实现整个空间分区的分配与回收。
3. 主要程序段及其解释:
#include <stdio.h> #include <stdlib.h> #include <string.h> const int CANUSE = 1; //未分配状态 const int CANTUSE = 0; //空表目状态 const int SIZE = 128; //初始化内存 //内存分区 struct Att { int begin_addr; //空闲区起始地址 int length; //一个连续空闲区的长度 int state; //状态 char task_name[32]; //内存中任务名 struct Att *next; //指向下一个空闲分区 }; //内存头指针 struct Att *head = NULL; //显示当前内存分配情况 void showsave() { struct Att *Mpoint = head; printf("内存的使用情况\n"); printf("begin_addr\tlength\tstate\ttask_name\n"); while( NULL!=Mpoint) { printf("%dk\t\t",Mpoint->begin_addr); printf("%dk\t",Mpoint->length); Mpoint->state?printf("CANUSE\t"):printf("CANTUSE\t"); printf("%s\n",Mpoint->task_name); Mpoint = Mpoint->next; } system("pause"); //输出Press any key to exit } //插入任务到空闲分区 int Ainsert(struct Att* Anew) { struct Att *Zinsert = head; //flag用于指示是Zinsert到了NULL,既没有内存可以分配 int flag = 1; while( Zinsert->length<Anew->length || !Zinsert->state) { if( NULL!=Zinsert->next ) { Zinsert = Zinsert->next; } else { Zinsert = Zinsert->next; break; } } if( NULL==Zinsert ) { return 0; } if( SIZE == Zinsert->begin_addr+Anew->length ) //分配完最后一块内存 { Zinsert->state = CANTUSE; strcpy(Zinsert->task_name , Anew->task_name); Zinsert->next = NULL; return 1; } else { struct Att *Ztail = (struct Att *)malloc(sizeof(struct Att)); Zinsert->state = CANTUSE; strcpy(Zinsert->task_name , Anew->task_name); Zinsert->length = Anew->length; Zinsert->next = Ztail; memset( Ztail, 0, sizeof(char)*32 ); Ztail->begin_addr = Zinsert->begin_addr + Anew->length; Ztail->state = CANUSE; Ztail->length = SIZE - Ztail->begin_addr; Ztail->next = NULL; return 1; } } //分配内存 void memoallocate(void) { struct Att *Anew = (struct Att*)malloc(sizeof(struct Att)); printf("输入要分配内存大小(kb):\n"); scanf("%d",&Anew->length); printf("输入任务名:\n"); scanf("%s",&Anew->task_name); Ainsert(Anew)?printf("分配内存成功\n"):printf("没有符合大小的空闲分区,内存分配失败。\n"); system("pause"); free(Anew); } //回收内存功能 int Mreturn(char taskname[]) { struct Att *front = NULL; struct Att *position = head; struct Att *tail = head->next; while( 0!=strcmp(position->task_name,taskname) ) { front = position; if( NULL!=position->next ) { position = position->next; } else { position = NULL; break; } tail = position->next; } if( NULL==position ) { printf("内存中没有此任务!"); } else { if( NULL!=tail&&NULL!=front ) { if( front->state&&tail->state ) { front->length = front->length + position->length + tail->length; front->next = tail->next; free(position); free(tail); } else if( front->state&&!tail->state ) { front->length = front->length + position->length; front->next = position->next; free(position); } else if( !front->state&&tail->state ) { position->length = position->length + tail->length; memset( position->task_name, 0, sizeof(char)*32 ); position->next = tail->next; position->state = CANUSE; free(tail); } else if( !front->state&&!tail->state ) { memset( position->task_name, 0, sizeof(char)*32 ); position->state = CANUSE; } } else if( NULL!=tail&&NULL==front ) { if( !tail->state ) { memset( position->task_name, 0, sizeof(char)*32 ); position->state = CANUSE; } else { position->length = position->length + tail->length; position->next = NULL; free(tail); } } else if( NULL==tail&&NULL!=front ) { if(front->state) { front->length = front->length + position->length; front->next = NULL; free(position); } else { memset( position->task_name, 0, sizeof(char)*32 ); position->state = CANUSE; } } else if( NULL==tail&&NULL==front ) { memset( position->task_name, 0, sizeof(char)*32 ); position->state = CANUSE; } printf("内存回收成功!\n"); } return 0; } //回收内存 void memoreturn(void) { char tname[32]; printf("输入要收回的任务名\n"); scanf("%s",tname); Mreturn(tname); system("pause"); } int main(void) { int f = 0; //初始化head head = (struct Att*)malloc(sizeof(struct Att)); head->begin_addr = 0; head->length = SIZE; head->state = CANUSE; memset(head->task_name, 0, sizeof(char)*32 ); head->next = NULL; while( 1 ) { printf("-----------主存分配和回收系统(首次适应算法)------------"); printf("\n1:查看内存分配情况\n"); printf("2:申请分配内存\n"); printf("3:申请回收内存\n"); printf("4:退出程序\n"); printf("\n"); scanf("%d",&f); switch( f ) { case 1 :showsave();break; case 2 :memoallocate();break; case 3 :memoreturn();break; case 4 :return 1; } system("cls"); //清屏操作 } }
4.运行结果
四、实验总结
在本次试验中,我详细的了解了每份内存的分配情况,我运用了链表来模拟每份内存的存放与消除,不过目前还只完成了一种算法,计划在本学期剩下的时间里运用空闲去了解其余的算法,体会更多种内存的分配方式