C++实现动态分区分配方式的模拟
动态分区分配方式的模拟
一、实验目的
了解动态分区分配方式中使用的数据结构和分配算法,并进一步加深对动态分区存储管理方式及其实现过程的理解。
二、实验环境
硬件环境:计算机一台,局域网环境;
软件环境: Windows或Linux操作系统, C语言编程环境。
三、实验内容
1、用C语言分别实现采用首次适应算法和最佳适应算法的动态分区分配过程alloc( )和回收过程free( )。其中,空闲分区通过空闲分区链来管理:在进行内存分配时,系统优先使用空闲区低端的空间。
2、假设初始状态下,可用的内存空间为640KB,并有下列的请求序列:
•作业1申请130KB。
•作业2申请60KB。
•作业3申请100KB。
•作业2释放60KB。
•作业4申请200KB。
•作业3释放100KB。
•作业1释放130KB。
•作业5申请140KB。
•作业6申请60KB。
•作业7申请50KB。
•作业6释放60KB。
请分别采用首次适应算法和最佳适应算法,对内存块进行分配和回收,要求每次分配和回收后显示出空闲分区链的情况。
3、实验报告要求:
(1)给出具体的设计过程,贴出相应的代码,截图给出试验结果。
(2)结合实验情况,谈谈你对存储管理的理解和体会。
四、C++实现代码
// 动态分区分配方式的模拟.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <stdbool.h>
#include <fstream>
#include <vector>
#include <algorithm>
#define totalMemory 640 //最大可用内存空间
using namespace std;
//kb类,代表每个kb的状态,是否占用,以及占用进程的ID是多少
class Kb {
public:
int ID; //当前占用该1kb内存的进程ID,如果没有占用则为0
bool isOccupy; //表示该1kb内存是否被占用,true表示已被占用
}Memory[totalMemory];
//事件类,记录每次事件,包括申请内存和释放内存。
class Event {
public:
int ID; //发生事件的进程的ID
int t; //t为1是申请内存,t为0是释放内存。
int amount; //若t为1,amount的值有效,它代表的是申请内存的数量。
};
//空闲区类,用来记录空闲区的开始位置、结束位置,和长度。
class freeArea {
public:
int length; //空闲区的长度
int begin; //空闲区开始的位置
int end; //空闲区结束的位置
};
//事件初始化
int event_Init(Event elist[]) {
int i = 0;
ifstream inf;
inf.open("G:\\source\\repos\\动态分区分配方式的模拟\\Debug\\data1.txt");
while (!inf.eof())
{
inf >> elist[i].ID ;
inf >> elist[i].t;
if (elist[i].t == 1)
{
inf >> elist[i].amount;
}
else
{
elist[i].amount = 0;
}
i++;
}
return i; //返回事件个数
}
//内存回收,并计算新的空闲内存区块数。
void memory_Recovery(Kb Memory[],vector<freeArea> &table, int ID) {
for (int i = 0; i < totalMemory; i++) //释放内存
{
if (Memory[i].ID == ID)
{
Memory[i].ID = 0;
Memory[i].isOccupy = false;
}
}
table.clear(); //清空旧的空闲分区表
int q = -1;
for (int i = 0; i < totalMemory; i++)
{
if (!Memory[i].isOccupy && (q == -1)) //记录空闲区开始位置
{
q = i;
i--; //防止大小为1的内存块儿出现。
}
else if ((q != -1) && Memory[i].isOccupy) //记录空闲区结束位置
{
//cout << i << endl;
freeArea k;
k.begin = q;
k.end = i - 1;
k.length = k.end - k.begin + 1;
table.push_back(k);
q = -1;
}
else if ((q != -1) && (i == totalMemory - 1)) //加上空闲区直到最后1kb的情况
{
//cout << i << endl;
freeArea k;
k.begin = q;
k.end = i;
k.length = k.end - k.begin + 1;
table.push_back(k);
q = -1;
}
}
}
//打印当前空闲分区表
void print_Table(vector<freeArea> table) {
cout << endl;
for (int i = 0; i < table.size(); i++)
{
cout << "\t" << i + 1 << "\t\t" << table[i].begin << "\t\t" << table[i].end << "\t\t" << table[i].length << endl;
}
}
//内存分配
void memory_allocate(Kb Memory[], int begin, int end, int ID) {
for (int i = begin; i < end; i++)
{
Memory[i].isOccupy = true;
Memory[i].ID = ID;
}
}
//将空闲分区表中的空闲分区,按开始位置从小到大的顺序排序。
bool cmp1(freeArea a, freeArea b) {
return a.begin < b.begin;
}
//首次适应算法(First Fit)
void FF(Kb Memory[], vector<freeArea> &table, Event elist[], int quantity) {
cout << "\n---------------------------首次适应算法----------------------------" << endl;
for (int i = 0; i < quantity; i++)
{
cout << "\n第" << i + 1 << "件事件后的空闲分区表" << endl;
cout << "空闲分区序号" << " 空闲分区开始" << " 空闲分区结束" << " 空闲分区长度";
if (elist[i].t == 1) //如果申请内存
{
int j = 0;
for(; j < table.size(); j++)
{
if (elist[i].amount <= table[j].length) break;
}
int q = table[j].begin;
memory_allocate(Memory, q, q + elist[i].amount, elist[i].ID);
memory_Recovery(Memory, table, -1);
sort(table.begin(), table.end(), cmp1);
print_Table(table);
}
else if (elist[i].t == 0) //如果释放内存
{
memory_Recovery(Memory, table, elist[i].ID);
sort(table.begin(), table.end(), cmp1);
print_Table(table);
}
}
}
//将空闲分区表中的空闲分区,按长度从小到大排序
bool cmp2(freeArea a, freeArea b) {
return a.length < b.length;
}
//最佳适应算法(Best Fit)
void BF(Kb Memory[], vector<freeArea>& table, Event elist[], int quantity) {
cout << "\n---------------------------最佳适应算法----------------------------" << endl;
for (int i = 0; i < quantity; i++)
{
cout << "\n第" << i + 1 << "件事件后的空闲分区表" << endl;
cout << "空闲分区序号" << " 空闲分区开始" << " 空闲分区结束" << " 空闲分区长度";
if (elist[i].t == 1)
{
int j = 0;
for (; j < table.size(); j++)
{
if (elist[i].amount <= table[j].length) break;
}
int q = table[j].begin;
memory_allocate(Memory, q, q + elist[i].amount, elist[i].ID);
memory_Recovery(Memory, table, -1);
sort(table.begin(), table.end(), cmp2);
print_Table(table);
}
else if (elist[i].t == 0)
{
memory_Recovery(Memory, table, elist[i].ID);
sort(table.begin(), table.end(), cmp2);
print_Table(table);
}
}
}
int main()
{
//初始化内存
for (int i = 0; i < totalMemory; i++)
{
Memory[i].ID = 0;
Memory[i].isOccupy = false;
}
//设置事件列表
Event elist[100];
int eventsQuantity = event_Init(elist); //事件个数
//cout << eventsQuantity << endl;
vector<freeArea> table; //定义空闲分区表
freeArea k;
k.begin = 0;
k.end = totalMemory - 1;
k.length = totalMemory;
table.push_back(k); //初始情况是一整块,所有有一个空闲分区。
event_Init(elist); //初始化事件
FF(Memory, table, elist, eventsQuantity); //首次适应算法
//cout << Memory[0].ID << endl;
for (int i = 0; i < totalMemory; i++) //重新初始化内存
{
Memory[i].ID = 0;
Memory[i].isOccupy = false;
}
table.clear(); //清空之前的空闲分区表
cout << endl;
table.push_back(k); //再次插入
BF(Memory, table, elist, eventsQuantity); //最佳适应算法
return 0;
}