操作系统实验2
实验二:存储管理动态分区分配及回收算法
一、实验目的
通过模拟动态分区分配和回收算法,理解内存管理的核心机制,掌握首次适应算法(First Fit)和最佳适应算法(Best Fit)的实现方法。
二、实验要求
1.实现首次适应算法和最佳适应算法。
2.编写空闲区回收算法,处理内存释放请求。
3.输出每次操作后的空闲区队列状态。
三、实验过程
1.准备
A. 查阅相关资料:学习分区描述器的结构和分配算法流程。
B. 初步编写程序:定义分区结构体(adr、size、next),初始化空闲队列(首址 0,大小32767)。
C. 准备测试数据:模拟多次分配和回收请求。
2.上机调试
测试分配算法是否按规则选择空闲区(First Fit选首个足够块,Best Fit选最小足够块)。
验证回收算法能否正确合并相邻空闲区。
3. 主要流程和源代码
1.用户选择算法。
2.输入操作类型(分配或回收)及参数(大小或首址)。
3.输出空闲区队列状态。
源代码:
#include <iostream>
#include <iomanip>
using namespace std;
// 分区描述器
struct node {
int adr;
int size;
node* next;
node(int a, int s) : adr(a), size(s), next(NULL) {}
};
// 全局指针
node* head1 = NULL;
node* back1 = NULL;
node* assign = NULL;
// 检查指定的释放块的合法性
bool check(int adr, int size) {
node* p = head1;
while (p) {
if (p->adr <= adr && adr + size <= p->adr + p->size) {
return true;
}
p = p->next;
}
return false;
}
// First Fit Algorithm
node* assignment1(int free) {
node* p = head1;
node* prev = NULL;
while (p) {
if (p->size >= free) {
if (p->size == free) {
if (prev) {
prev->next = p->next;
} else {
head1 = p->next;
}
return p;
} else {
node* newNode = new node(p->adr, free);
p->adr += free;
p->size -= free;
return newNode;
}
}
prev = p;
p = p->next;
}
return NULL;
}
// Best Fit Algorithm
node* assignment2(int free) {
node* p = head1;
node* best = NULL;
node* prevBest = NULL;
node* prev = NULL;
while (p) {
if (p->size >= free) {
if (!best || p->size < best->size) {
best = p;
prevBest = prev;
}
}
prev = p;
p = p->next;
}
if (best) {
if (best->size == free) {
if (prevBest) {
prevBest->next = best->next;
} else {
head1 = best->next;
}
return best;
} else {
node* newNode = new node(best->adr, free);
best->adr += free;
best->size -= free;
return newNode;
}
}
return NULL;
}
// First Fit Algorithm 的回收算法
void acceptance1(int adr, int size) {
node* newNode = new node(adr, size);
if (!head1) {
head1 = newNode;
return;
}
node* p = head1;
node* prev = NULL;
while (p && p->adr < adr) {
prev = p;
p = p->next;
}
if (prev && prev->adr + prev->size == adr) {
prev->size += size;
if (p && adr + size == p->adr) {
prev->size += p->size;
prev->next = p->next;
delete p;
}
delete newNode;
} else if (p && adr + size == p->adr) {
p->adr = adr;
p->size += size;
delete newNode;
} else {
if (prev) {
prev->next = newNode;
newNode->next = p;
} else {
newNode->next = head1;
head1 = newNode;
}
}
}
// Best Fit Algorithm 的回收算法
void acceptance2(int adr, int size) {
acceptance1(adr, size); // 回收逻辑相同
}
// 打印空闲区队列
void print() {
node* p = head1;
int num = 1;
cout << setw(10) << "编号" << setw(10) << "首址" << setw(10) << "终址" << setw(10) << "大小" << endl;
while (p) {
cout << setw(10) << num++ << setw(10) << p->adr << setw(10) << p->adr + p->size - 1 << setw(10) << p->size << endl;
p = p->next;
}
cout << "----------------------------------" << endl;
}
int main() {
// 申请一整块空闲区
head1 = new node(0, 32767);
int choice, action;
int free;
int adr, size;
while (true) {
cout << "选择分配算法 (1: First Fit 2: Best Fit): ";
cin >> choice;
cout << "选择操作 (1: 分配 2: 回收 3: 另一种回收 4: 退出): ";
cin >> action;
if (action == 1) {
cout << "输入申请区的大小: ";
cin >> free;
if (choice == 1) {
assign = assignment1(free);
} else {
assign = assignment2(free);
}
if (assign) {
cout << "分配成功!" << endl;
} else {
cout << "分配失败!" << endl;
}
} else if (action == 2) {
cout << "输入释放区的首址和大小: ";
cin >> adr >> size;
if (check(adr, size)) {
if (choice == 1) {
acceptance1(adr, size);
} else {
acceptance2(adr, size);
}
cout << "回收成功!" << endl;
} else {
cout << "释放块不合法!" << endl;
}
} else if (action == 3) {
// 另一种回收操作的逻辑
} else if (action == 4) {
break;
}
// 输出空闲区队列情况
print();
}
// 释放内存
while (head1) {
node* temp = head1;
head1 = head1->next;
delete temp;
}
return 0;
}
4.遇到的主要问题和解决方法
A. :回收时未合并相邻空闲区。
解决:在回收函数中增加相邻块检查逻辑。
B. :Best Fit算法效率低。
解决:优化空闲区队列的遍历方式。
四、实验结果
1.测试 First Fit 算法的分配
- 测试 First Fit 算法的回收:
- 测试 Best Fit 算法的分配:
- 测试 Best Fit 算法的回收:
五、实验总结
本次实验不仅让我掌握了两种经典的动态分区分配回收算法,更让我认识到内存管理在操作系统中的重要性及其复杂性。通过对比 First Fit 和 Best Fit 算法的实验结果,我直观感受到不同算法在时间效率和空间利用率上的权衡,这为后续学习其他内存管理策略奠定了基础。在实验过程中,我也意识到自身在代码优化和异常处理方面的不足,例如未充分考虑极端情况下的内存分配回收场景,部分代码逻辑可进一步简化以提高执行效率。这些不足为我后续学习指明了方向。