C++实现伙伴算法,操作系统内存分配算法

内容:基于内存管理的伙伴算法,实现内存块申请时的分配和释放后的回收(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&&current->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;
		}
	}
}

  • 6
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值