动态分区分配实验报告
时间: 2023-08-21 22:07:39 浏览: 56
动态分区分配是一种内存管理技术,将内存分成若干个区域,每个区域的大小不同,根据程序的需要进行分配和回收。该技术可以提高内存利用率,减少内存碎片,并且可以动态调整内存分配,适应不同的应用场景。
本次实验主要是通过模拟动态分区分配的过程,来加深对动态分区分配的理解。
实验环境及工具:C++ 编译器,Visual Studio 2019。
实验步骤:
1. 定义数据结构
首先我们定义一个内存块的结构体,包含该内存块的起始地址、大小、是否被分配等信息:
```c++
struct MemoryBlock {
int startAddr; // 起始地址
int size; // 大小
bool isFree; // 是否被分配
};
```
2. 模拟内存分配
接下来我们模拟内存的分配过程。首先定义一个动态数组来保存内存块的信息,然后按照一定的规则进行内存分配。这里我们采用了首次适应算法(First Fit)来进行内存分配:
```c++
void allocateMemory(vector<MemoryBlock>& mem, int size) {
for (int i = 0; i < mem.size(); i++) {
if (mem[i].isFree && mem[i].size >= size) {
mem[i].isFree = false;
if (mem[i].size > size) {
MemoryBlock newBlock = { mem[i].startAddr + size, mem[i].size - size, true };
mem.insert(mem.begin() + i + 1, newBlock);
}
mem[i].size = size;
cout << "分配了 " << size << "KB 内存,起始地址为 " << mem[i].startAddr << "KB" << endl;
return;
}
}
cout << "内存不足,无法分配" << endl;
}
```
该函数遍历内存块数组,找到第一个空闲内存块大小大于等于需要分配的内存大小的内存块,并将其分配出去。如果该内存块大小大于分配的大小,则将剩余部分插入到内存块数组中。
3. 模拟内存回收
当程序不再需要某个内存块时,需要将该内存块回收,以便下一次分配。这里我们采用了合并相邻空闲块的方法来进行内存回收。
```c++
void freeMemory(vector<MemoryBlock>& mem, int startAddr) {
for (int i = 0; i < mem.size(); i++) {
if (mem[i].startAddr == startAddr) {
mem[i].isFree = true;
cout << "已释放 " << mem[i].size << "KB 内存,起始地址为 " << mem[i].startAddr << "KB" << endl;
if (i > 0 && mem[i - 1].isFree) {
mem[i - 1].size += mem[i].size;
mem.erase(mem.begin() + i);
i--;
}
if (i < mem.size() - 1 && mem[i + 1].isFree) {
mem[i].size += mem[i + 1].size;
mem.erase(mem.begin() + i + 1);
}
return;
}
}
cout << "该内存块不存在,无法释放" << endl;
}
```
该函数遍历内存块数组,找到需要回收的内存块,并将其标记为空闲。然后检查该内存块的前后是否有空闲内存块,如果有,则将它们合并成一个更大的空闲内存块。
4. 模拟内存使用
最后,我们编写一个简单的程序来模拟内存的使用。该程序会不断地进行内存分配和回收,并且每次进行操作后会输出当前内存块数组的信息。
```c++
int main() {
vector<MemoryBlock> mem;
mem.push_back({ 0, 1024, true }); // 初始化内存块
while (true) {
cout << "1. 分配内存" << endl;
cout << "2. 释放内存" << endl;
cout << "3. 查看内存情况" << endl;
cout << "4. 退出" << endl;
cout << "请输入操作编号:";
int choice, size, addr;
cin >> choice;
switch (choice) {
case 1:
cout << "请输入需要分配的内存大小(KB):";
cin >> size;
allocateMemory(mem, size);
break;
case 2:
cout << "请输入需要释放的内存起始地址(KB):";
cin >> addr;
freeMemory(mem, addr);
break;
case 3:
for (int i = 0; i < mem.size(); i++) {
cout << "起始地址:" << mem[i].startAddr << "KB,大小:" << mem[i].size << "KB,状态:";
if (mem[i].isFree) {
cout << "空闲" << endl;
} else {
cout << "已分配" << endl;
}
}
break;
case 4:
return 0;
default:
cout << "操作编号无效,请重新输入" << endl;
}
}
return 0;
}
```
实验结果:
运行程序后,可以看到以下界面:
```
1. 分配内存
2. 释放内存
3. 查看内存情况
4. 退出
请输入操作编号:
```
输入 1 可以进行内存分配,输入 2 可以进行内存回收,输入 3 可以查看当前内存块数组的情况,输入 4 可以退出程序。下面是一些操作示例:
```
请输入操作编号:1
请输入需要分配的内存大小(KB):256
分配了 256KB 内存,起始地址为 0KB
请输入操作编号:1
请输入需要分配的内存大小(KB):512
分配了 512KB 内存,起始地址为 256KB
请输入操作编号:3
起始地址:0KB,大小:256KB,状态:已分配
起始地址:256KB,大小:512KB,状态:已分配
请输入操作编号:2
请输入需要释放的内存起始地址(KB):0
已释放 256KB 内存,起始地址为 0KB
请输入操作编号:3
起始地址:0KB,大小:768KB,状态:空闲
请输入操作编号:4
```
可以看到,程序可以正常进行内存分配和回收,并且在操作后正确地合并了相邻空闲块,保证了内存块的连续性。
总结:
通过本次实验,我们深入了解了动态分区分配的原理,掌握了内存分配和回收的实现方法,提高了对内存管理的理解。