实验七 动态分区分配算法

这篇博客详细介绍了使用C++实现内存管理的过程,包括动态分配、首次、最佳和最坏分配算法,以及内存的释放和查询。通过结构体指针实现内存块的存储,避免了数组的局限性,并提供了简化版的内存合并操作。

不知道是不是理解错误,感觉最近的几个实验都大同小异。
用算法思想描述就是(又是一个模拟题,甚至不需要考虑空间和时间复杂度。

设立全局变量和所需结构:

#define getpch(type) (type*)malloc(sizeof(type)) //指针建立的重命名

struct ava_memory{
   
    //可用内存块存储.
	int ID; //标记进程的号码,如果该区块未被进程占用,那么我们认为为-1.
	int start; //当前区块的开始位置.
	int end; //当前区块的结束位子.
	int len; //当前区块的长度.
	struct ava_memory *next; //我们利用指针来模拟,所以需要一个连接指针.
};
struct ava_memory *avaoc; //建立头指针.

int memory, ide; //建立全局下的变量:总内存 和 当前进程号.
bool run; //执行判断条件.
string ins; //操作选择变量.

来讲一下为我何选用结构体指针来实现,而不是结构体数组:
  使用数组的话的优势区间?可以O(1)访问进程块,但是这无法弥补需要反复“移动”的缺陷。所以我更趋向于使用指针来实现,这样我们就方便修改进程块的修改。
  使用指针,那么我们只能每次从头遍历,如果需要优化,可以建立哈希表存储各进程的指针。(我比较懒,就不进行实现了。

对建立的结构进行初始化:

void new_work(){
   
    //初始化操作
	cout << " please the Total system memory size: "; //提示语句
	cin >> memory; //总内存的输入
	run = true; //循环成立条件
	ide = 1; //初始化进程号
	struct ava_memory *q = getpch(struct ava_memory); //给头指针分配空间,作为最开始的内存块
	avaoc = q; //将建立的空间索引给全局下的头指针
	avaoc->start = 1, avaoc->end = memory, avaoc->len = memory, avaoc->ID = -1, avaoc->next = NULL; //头指针的初始化
	
	cout << endl; //对初始化的结果观测
	cout << " new~" << endl;
	cout << " start:" << avaoc->start << " end:" << avaoc->end << " len:" << avaoc->len << " ID:" << avaoc->ID << " next:" << avaoc->next << endl << endl;
}

  初始化的作用: 因为我的想法是开始的数据结构中就有一个ID号为 -1 (即是一个未分配进程的内存块)。它的开始位子就是1,而结束位子和总长度就是我们分配给的内存。

动态分配内存:

void add(){
   
    //添加操作还是很好写的啦啦啦
	cout << endl;
	cout << " please input the size of memory: ";
	int Size; cin >> Size;
	if(memory < Size) {
   
   cout << " The memory is not enough!" << endl << endl; return; } //判断内存是否足够
	memory -= Size; //更改剩余内存
	
	cout << " adding~... ..." << endl;
	struct ava_memory *head = avaoc; //建立用来遍历的指针
	
	while(head && Size){
   
   
		if(head->ID == -1){
   
    //-1 表示未被进程占用
			if(Size <= head->len){
   
    //当该内存块足够分配的时候
				if(Size < head->len){
   
    //这是需要建立新的内存块的操作
					int b_end = head->end; //备份
					head->end = head->start + Size - 1; //-1 算上初始位
					head->len = Size;
					struct ava_memory *p = getpch(struct ava_memory);
					p->start = head->end + 1, p->end = b_end, p->len = p->end - p->start + 1, p->ID = -1, p->next = head->next;
					head->next = p;
				}
				Size = 0 , head->ID = ide;
			}else{
   
    //当当前内存块不足以进行分配内存时,那么该整块内存都分配给这个进程
				Size -= head->len;
				head->ID = ide;
			}
		}
		
		head = head -> next;
	}
	
	ide ++; //标记当前进程号
	cout << endl;
}

  预想的动态分配内存: 对无法一个空闲内存块的进行分块存储,即对进程的分割。那么我们如何进行分配呢?如果所需的内存大于等于当前所在的空闲内存块,那么我们只需要修改进程号,当作该内存块全部分配给了当前进程。如果所需的内存大小 小于所在的内存块,那么我们需要对这个进程块进行分割(进程剩余所需内存块 和 所在空闲内存块的剩余内存)。实际操作就是,建立一个新的指针添加在这个指针后面,然后修改一些参数。
在这里插入图片描述
注意:上面的分配和下面的首次,最佳,最坏分配不在一个代码中实现。

首次分配算法:

void first_malloc(){
   
   
	add(); //该处不是上面那个分配内存的方法,而是输入语句
	cout << endl;
	struct ava_memory *p = avaoc;
	bool m = true;
	while(p){
   
   
		if(p->ID == -1 && p->len >= sum){
   
    //寻找一个能够分配的进程块
			if(p->len > sum){
   
    //这部分还是一样的,如果刚刚好,那么只需要修改进程号即可,但是如果需要分配的内存小于当前空闲内存块,那么分块处理.
				int b_end = p->end;
				p->end = p->start + sum - 1; //-1 算上初始位
				p->len = sum;
				struct ava_memory *q = getpch(struct ava_memory);
				q->ID = -1, q->start = p->start + sum, q->end = b_end, q->len = q->end - q->start + 1, q->next = p->next;
				p->next = q;
			}
			p->ID = ide;
			m = false;
			break; //一旦找到就退出,因为就分配一个
		}
		p = p->next;
	}
	if(m){
   
    //如果没找到,那么就是没有一个进程块能放下这个完整的进程
		cout << "you can not do this, your memory is not enough!" << endl << endl;
		return;
	}
	cout << " first_malloc~... ..." << endl << endl;
	ide ++;
}

  首次分配算法就时遇到第一个能够分配进的内存块那么我们就分配。遍历链表的同时进行修改,修改完成后直接跳出遍历。(我这里实现的是如果没找到单个内存块就表示无法执行。
在这里插入图片描述

最佳分配算法:

void min_malloc(){
   
   
	add();
	cout << endl;
	int num = memory;
	struct ava_memory *head = avaoc;
	struct ava_memory *p = NULL;
	
	while(head){
   
    //找到能够分配进去的最小的进程块
		if(head->ID == -1 && head->len >= sum && head->len < num) p = head , num = head->len;
		head = head->next;
	}
	
	if(p && p->len > sum){
   
    //既然找到了最小的能够
		int b_end = p->end;
		p->end = p->start + sum - 1; //-1 算上初始位
		p->len = sum;
		struct ava_memory *q = getpch(struct ava_memory);
		q->ID = -1, q->start = p->start + sum, q->end = b_end, q->len = q->end - q->start + 1, q->next = p->next;
		p->next = q;
		p->ID = ide;
	}else{
   
   
		cout << "you can not do this, your memory is not enough!" << endl << endl;
		return;
	}
	cout << " min_malloc~... ..." << endl << endl;
	ide ++
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值