实验三 存储管理
一、实验目的
通过实验使学生了解可变式分区管理使用的主要数据结构,分配、回收的主要技术,了解最优适应分配、最坏适应分配、最先适应分配和循环适应分配等分配算法。基本能达到下列具体的目标:
- 掌握初步进程在内存中的映像所需要的内存需求。
- 内存的最先分配算法首先实现,再逐步完成最优和最坏的分配算法。
二、实验内容
- 在进程管理的基础上实现内存分配和回收。
- 学生了解实验目的,画出流程框图。
- 复习单向链操作编程,编写全部程序。能够实现多种分配算法。
- 创建和撤消进程时,完成内存的分配和回收操作,必须可以显示空闲内存块队列状态。注意回收内存时,空闲块的合并操作。
- 学生要在上一次实验的基础上对队列的删除、插入进一步熟练。
- 程序设计(原理、数据结构设计、流程图)
1. 原理
该程序实现了一个简单的内存管理器,支持多种内存分配策略(如首次适应、最佳适应、最坏适应和下一个适应)。内存管理器通过链表结构管理空闲内存块,允许动态分配和释放内存。
2. 数据结构设计
MemoryBlock: 结构体表示一个内存块,包含起始地址、大小和指向下一个内存块的指针。
MemoryManager: 类管理内存块的分配和释放,维护一个空闲内存块的链表。
- 流程图
(2)核心函数
// ... existing code ...
int allocate(int size, const std::string& strategy) {
if (size <= 0) return -1;
if (strategy == "first_fit") {
return firstFitAllocate(size);
}
else if (strategy == "best_fit") {
return bestFitAllocate(size);
}
else if (strategy == "worst_fit") {
return worstFitAllocate(size);
}
else if (strategy == "next_fit") {
return nextFitAllocate(size);
}
return -1;
}
// ... existing code ...
void deallocate(int start, int size) {
MemoryBlock* newBlock = new MemoryBlock(start, size);
MemoryBlock* current = freeList;
MemoryBlock* prev = nullptr;
// 找到插入点
while (current && current->start < start) {
prev = current;
current = current->next;
}
// 插入新的空闲块
if (prev) {
prev->next = newBlock;
}
else {
freeList = newBlock;
}
newBlock->next = current;
// 合并相邻的空闲块
mergeFreeBlocks();
}
// ... existing code ...
private:
int firstFitAllocate(int size) {
MemoryBlock* current = freeList;
while (current) {
if (current->size >= size) {
int start = current->start;
current->start += size;
current->size -= size;
if (current->size == 0) {
// 如果当前块被完全分配,移除它
if (current == freeList) {
freeList = current->next;
}
else {
MemoryBlock* prev = freeList;
while (prev->next != current) {
prev = prev->next;
}
prev->next = current->next;
}
delete current;
}
return start; // 返回分配的起始地址
}
current = current->next;
}
return -1; // 分配失败
}
// ... existing code ...
allocate 函数根据用户选择的策略调用相应的分配函数。
deallocate 函数负责释放指定内存块并合并相邻的空闲块。
firstFitAllocate 函数实现了首次适应算法,查找第一个足够大的空闲块进行分配。
(3)测试截图
源码:
#include <iostream>
#include <vector>
#include <limits>
struct MemoryBlock {
int start; // 内存块的起始地址
int size; // 内存块的大小
MemoryBlock* next; // 指向下一个内存块的指针
MemoryBlock(int s, int sz) : start(s), size(sz), next(nullptr) {}
};
class MemoryManager {
private:
MemoryBlock* freeList; // 空闲内存块链表
int totalSize; // 总内存大小
public:
MemoryManager(int size) : totalSize(size) {
freeList = new MemoryBlock(0, size); // 初始化一个大的空闲块
}
~MemoryManager() {
// 释放内存块
while (freeList) {
MemoryBlock* temp = freeList;
freeList = freeList->next;
delete temp;
}
}
void printFreeList() {
std::cout << "Free memory blocks:\n";
MemoryBlock* current = freeList;
while (current) {
std::cout << "Start: " << current->start << ", Size: " << current->size << "\n";
current = current->next;
}
}
int allocate(int size, const std::string& strategy) {
if (size <= 0) return -1;
if (strategy == "first_fit") {
return firstFitAllocate(size);
}
else if (strategy == "best_fit") {
return bestFitAllocate(size);
}
else if (strategy == "worst_fit") {
return worstFitAllocate(size);
}
else if (strategy == "next_fit") {
return nextFitAllocate(size);
}
return -1;
}
void deallocate(int start, int size) {
// 释放内存块并合并空闲块
MemoryBlock* newBlock = new MemoryBlock(start, size);
MemoryBlock* current = freeList;
MemoryBlock* prev = nullptr;
// 找到插入点
while (current && current->start < start) {
prev = current;
current = current->next;
}
// 插入新的空闲块
if (prev) {
prev->next = newBlock;
}
else {
freeList = newBlock;
}
newBlock->next = current;
// 合并相邻的空闲块
mergeFreeBlocks();
}
private:
int firstFitAllocate(int size) {
MemoryBlock* current = freeList;
while (current) {
if (current->size >= size) {
int start = current->start;
current->start += size;
current->size -= size;
if (current->size == 0) {
// 如果当前块被完全分配,移除它
if (current == freeList) {
freeList = current->next;
}
else {
MemoryBlock* prev = freeList;
while (prev->next != current) {
prev = prev->next;
}
prev->next = current->next;
}
delete current;
}
return start; // 返回分配的起始地址
}
current = current->next;
}
return -1; // 分配失败
}
int bestFitAllocate(int size) {
MemoryBlock* current = freeList;
MemoryBlock* bestFit = nullptr;
MemoryBlock* bestFitPrev = nullptr;
// 找到最适合的块
while (current) {
if (current->size >= size) {
if (!bestFit || current->size < bestFit->size) {
bestFit = current;
bestFitPrev = nullptr;
}
}
current = current->next;
}
if (bestFit) {
int start = bestFit->start;
bestFit->start += size;
bestFit->size -= size;
if (bestFit->size == 0) {
// 如果当前块被完全分配,移除它
if (bestFit == freeList) {
freeList = bestFit->next;
}
else {
MemoryBlock* prev = freeList;
while (prev->next != bestFit) {
prev = prev->next;
}
prev->next = bestFit->next;
}
delete bestFit;
}
return start; // 返回分配的起始地址
}
return -1; // 分配失败
}
int worstFitAllocate(int size) {
MemoryBlock* current = freeList;
MemoryBlock* worstFit = nullptr;
MemoryBlock* worstFitPrev = nullptr;
// 找到最坏适合的块
while (current) {
if (current->size >= size) {
if (!worstFit || current->size > worstFit->size) {
worstFit = current;
worstFitPrev = nullptr;
}
}
current = current->next;
}
if (worstFit) {
int start = worstFit->start;
worstFit->start += size;
worstFit->size -= size;
if (worstFit->size == 0) {
// 如果当前块被完全分配,移除它
if (worstFit == freeList) {
freeList = worstFit->next;
}
else {
MemoryBlock* prev = freeList;
while (prev->next != worstFit) {
prev = prev->next;
}
prev->next = worstFit->next;
}
delete worstFit;
}
return start; // 返回分配的起始地址
}
return -1; // 分配失败
}
int nextFitAllocate(int size) {
static MemoryBlock* lastAllocated = nullptr; // 记录上次分配的位置
MemoryBlock* current = lastAllocated ? lastAllocated : freeList;
while (current) {
if (current->size >= size) {
int start = current->start;
current->start += size;
current->size -= size;
if (current->size == 0) {
// 如果当前块被完全分配,移除它
if (current == freeList) {
freeList = current->next;
}
else {
MemoryBlock* prev = freeList;
while (prev->next != current) {
prev = prev->next;
}
prev->next = current->next;
}
delete current;
}
lastAllocated = current; // 更新上次分配的位置
return start; // 返回分配的起始地址
}
current = current->next;
}
// 如果没有找到,继续从头开始搜索
current = freeList;
while (current) {
if (current->size >= size) {
int start = current->start;
current->start += size;
current->size -= size;
if (current->size == 0) {
// 如果当前块被完全分配,移除它
if (current == freeList) {
freeList = current->next;
}
else {
MemoryBlock* prev = freeList;
while (prev->next != current) {
prev = prev->next;
}
prev->next = current->next;
}
delete current;
}
lastAllocated = current; // 更新上次分配的位置
return start; // 返回分配的起始地址
}
current = current->next;
}
return -1; // 分配失败
}
private:
void mergeFreeBlocks() {
if (!freeList) return; // 如果空闲列表为空,直接返回
MemoryBlock* current = freeList;
MemoryBlock* nextBlock = current->next;
while (nextBlock) {
// 情况 1: 前空后不空
if (current->start + current->size == nextBlock->start) {
// 合并当前块和下一个块
current->size += nextBlock->size; // 合并大小
current->next = nextBlock->next; // 跳过下一个块
delete nextBlock; // 释放内存
nextBlock = current->next; // 更新下一个块
}
// 情况 2: 前不空后空
else if (current->start + current->size < nextBlock->start) {
// 当前块和下一个块不相邻,直接移动到下一个块
current = nextBlock; // 移动到下一个块
nextBlock = nextBlock->next; // 更新下一个块
}
// 情况 3: 前后都空
else {
// 这种情况在当前逻辑中不需要特别处理,因为我们只处理相邻块的合并
// 继续移动到下一个块
current = nextBlock; // 移动到下一个块
nextBlock = nextBlock->next; // 更新下一个块
}
}
}
};
int main() {
MemoryManager memoryManager(100); // 创建内存管理器,总内存为100
std::string strategy;
while (true) {
std::cout << "输入想要的分配算法 (first_fit, best_fit, worst_fit, next_fit) or 'exit' to quit: ";
std::cin >> strategy;
if (strategy == "exit") break;
int size;
std::cout << "输入要分配的内存大小 ";
std::cin >> size;
int address = memoryManager.allocate(size, strategy);
if (address != -1) {
std::cout << "分配的内存位于: " << address << "\n";
}
else {
std::cout << "分配失败!\n";
}
memoryManager.printFreeList(); // 打印空闲内存块状态
std::cout << "输入要取消分配的大小: ";
std::cin >> size;
memoryManager.deallocate(address, size); // 释放内存
memoryManager.printFreeList(); // 打印空闲内存块状态
}
return 0;
}