内容:基于内存管理的伙伴算法,实现内存块申请时的分配和释放后的回收(malloc/free),同时在回收过程中可对块进行合并。
#include<iostream>
#include<iomanip>
#include<random>
#include<cmath>
using namespace std;
int TOTAL_MEMORY =32;//内存总大小,必须是2的整数倍
int apply_arr[] = { 100, 250, 200,1,2 }; //申请序列
int memory_apply(int);
int memory_recover(int);
void print_mem();
void free_space();
void merge_empty_blocks();
struct empty_space {//空闲分区
int start;
int size;
struct empty_space* next;
struct empty_space* front;
};
typedef struct empty_space empty_space;
empty_space* eHead=NULL;
struct allocated_space {//已分配分区
int start;
int size;
int needed;
struct allocated_space* next;
struct allocated_space* front;
};
typedef struct allocated_space allocated_space;
allocated_space* aHead=NULL;
void apply(int size) {
int alloc = memory_apply(size);
if (alloc != 0)
TOTAL_MEMORY -= alloc;
else {
if (TOTAL_MEMORY >= size)
cout << "由于碎片而不能满足此内存申请\n";
else
cout << "由于空间不足而不能满足此内存申请\n";
}
}
int main() {
empty_space * eblock=new empty_space;
eblock->start = 1;
eblock->size = TOTAL_MEMORY;
eblock->next = NULL;
eblock->front = NULL;
eHead = eblock;
while (1) {
cout << "1:申请 2:序列申请 3:回收 4:一键回收 5:打印内存使用情况" << endl;
int op ;
cin >> op;
if (op == 1) {
int size;
cout << "输入申请内存大小:";
cin >> size;
apply(size);
}
else if (op == 2) {
for (int i = 0; i < sizeof(apply_arr)/sizeof(int); i++) {
apply(apply_arr[i]);
}
}
else if (op == 3) {
int size;
cout << "输入回收内存大小:";
cin >> size;
int rec=memory_recover(size);
if (rec == 0) {
merge_empty_blocks();
}
else {
TOTAL_MEMORY += rec;
}
}
else if (op == 4) {
free_space();
break;
}
else if (op == 5) {
print_mem();
}
}
return 0;
}
int memory_apply(int m){
//寻找应分配大小
int z = 0;
for (int i = 0; i < 10; i++) {
if (m >= pow(2 , i) && m <= pow(2 , (i + 1))){
z = i+1;
break;
}
}
if (z == 0)
return 0;
int alloc = pow(2, z);//应分配大小
//cout << needed<<endl;
empty_space* eP = eHead;
while (eP != NULL) {
if (eP->size < alloc) {
eP = eP->next;
}
else {//eP.size>=needed
//先分割
int times = eP->size;
while (times != alloc) {
times /= 2;
eP->size = times ;
empty_space* eblock = new empty_space;
eblock->size = times;
eblock->start = eP->start+times ;
eblock->next = eP->next;
eblock->front = eP;
if(eblock->next!=NULL)
eblock->next->front = eblock;
eP->next = eblock;
}
//再分配
allocated_space* ablock = new allocated_space;
if (eP->front == NULL) {
ablock->needed = m;
ablock->size = eP->size;
ablock->start = eP->start;
ablock->next = NULL;
ablock->front = NULL;
if (aHead == NULL)
aHead = ablock;
else {
ablock->next = aHead;
aHead->front = ablock;
aHead = ablock;
}
eHead = eP->next;
if (eP->next != NULL)
eHead->front = NULL;
delete eP;
}
else {
ablock->needed = m;
ablock->size = eP->size;
ablock->start = eP->start;
ablock->next = NULL;
ablock->front = NULL;
if (aHead == NULL)
aHead = ablock;
else {
ablock->next = aHead;
aHead->front = ablock;
aHead = ablock;
}
eP->front->next = eP->next;
if(eP->next!=NULL)
eP->next->front = eP->front;
delete eP;
}
cout << "applied " << ablock->size << "B of memory from address "<<ablock->start << endl;
return alloc;
break;
}
}
if (eP == NULL) {
return 0;
cout << "内存分配失败!" << endl;
}
}
int memory_recover(int m){
empty_space* P = eHead;
allocated_space* PP = aHead;
while (PP != NULL) {
if (PP->needed == m) {
if (PP->front != NULL) {
PP->front->next = PP->next;
}
else {
aHead = PP->next;
}
if(PP->next!=NULL)
PP->next->front = PP->front;
int size = PP->size;
int start = PP->start;
// 将回收的内存块添加到空闲块链表中
empty_space* newEmptyBlock = new empty_space;
newEmptyBlock->start = PP->start;
newEmptyBlock->size = PP->size;
newEmptyBlock->next = NULL;
newEmptyBlock->front = NULL;
delete PP;
if (P == NULL) {
eHead = newEmptyBlock;
cout << "recovered " << size << "B of memory from " << start << endl;
}
else {
while (P != NULL) {
//寻找回收块该放入的位置, 合并相邻的空闲块
if (newEmptyBlock->start <eHead->start) {
newEmptyBlock->next = eHead;
eHead->front = newEmptyBlock;
eHead = newEmptyBlock;
cout << "recovered " << size << "B of memory from " << start << endl;
merge_empty_blocks();
break;
}
else if (newEmptyBlock->start >= P->start + P->size && P->next == NULL) {
P->next = newEmptyBlock;
newEmptyBlock->front = P;
merge_empty_blocks();
cout << "recovered " << size << "B of memory from " << start << endl;
break;
}
else if ((newEmptyBlock->start >= P->start + P->size)&&(newEmptyBlock->start+newEmptyBlock->size<=P->next->start)) {
newEmptyBlock->next = P->next;
newEmptyBlock->front = P;
P->next = newEmptyBlock;
newEmptyBlock->next->front = newEmptyBlock;
cout << "recovered " << size << "B of memory from " << start << endl;
merge_empty_blocks();
break;
}
else {
P = P->next;
}
}
}
return size;
}
else {
PP = PP->next;
}
}
return 0;
}
void print_mem() {
empty_space* P = eHead;
allocated_space* PP = aHead;
cout << "未分配:" << endl;
while (P != NULL) {
cout << "Start:" << setw(15) << left << P->start << "Size:" << setw(15) << left << P->size << endl;
P = P->next;
}
cout << "已分配:" << endl;
while (PP != NULL) {
cout <<"Start:" << setw(15) << left << PP->start << "Size:" << setw(15) << left << PP->size <<"Needed:" << setw(15) << left << PP->needed << endl;
PP = PP->next;
}
}
void free_space()//释放内存分配信息链表
{
if (eHead != NULL) {
if (eHead->next != NULL) {
eHead = eHead->next;
delete []eHead->front;
}
else
delete []eHead;
}
if (aHead != NULL) {
if (aHead->next != NULL) {
aHead = aHead->next;
delete []aHead->front;
}
else
delete []aHead;
}
}
void merge_empty_blocks() {
empty_space* current = eHead;
while (current != NULL && current->next != NULL) {
// 检查当前相邻块大小是否相等
if ( current->size == current->next->size&¤t->size+current->start==current->next->start) {
if (((current->next->start - 1 )/ current->size) % 2 == 1) {
// 合并相邻块
current->size += current->next->size;
empty_space* temp = current->next;
// 从链表中移除下一个块
current->next = current->next->next;
if (current->next != NULL) {
current->next->front = current;
}
// 释放被合并的块的内存
delete temp;
}
else {
current = current->next;
}
}
else {
current = current->next;
}
}
}