os 首次适应算法FF主存分配回收

2主存空间的分配和回收

可变分区管理方式下采用首次适应算法(FF)实现主存分配和回收

[提示]:
(1) 可变分区方式是按作业需要的主存空间大小来分割分区的。当要装入一个作业时,根据作业需要的主存容量查看是否有足够的空闲空间,若有,则按需分配,否则,作业无法装入。假定内存大小为128K,空闲区说明表格式为:

  • 分区号——表示是第几个空闲分区;
  • 起始地址——指出空闲区的起始地址;
  • 长度——一个连续空闲区的长度;

(2) 采用首次适应算法分配回收内存空间。运行时,输入一系列分配请求和回收请求。
要求能接受来自键盘的空间申请及释放请求,能显示分区分配及回收后的内存布局情况。

*基于顺序搜索的动态分区分配算法有FF(首次适应算法),NF(循环首次适应算法),BF(最佳适应算法),WF(最坏适应算法)。

所以我数据结构用双向链(空闲分区链),查找时从链首开始顺序查找。

#include "pch.h"
#include<iostream>
#include<string>
using namespace std;

int num = 3;//标记内存中载入了几个进程
//随便设内存大小为128好了
int Memory[128] = {
	0,0,0,0,0,0,0,0,0,1,
	1,1,1,1,1,1,2,2,2,2,
	2,2,2,0,0,0,0,0,0,0,
	0,0,0,0,0,0,0,0,3,3,
	3,3,3,3,3,3,0,0,0,0,
	0,0,0,0,0,0,0,0,0,0,
	0,0,0,0,0,0,0,0,0,0,
	0,0,0,0,0,0,0,0,0,0,
	0,0,0,0,0,0,0,0,0,0,
	0,0,0,0,0,0,0,0,0,0,
	0,0,0,0,0,0,0,0,0,0,
	0,0,0,0,0,0,0,0
};

//空闲分区结点FreeBlock
struct FB {
	int FBid=0;
	int startAddr=0;
	int len=0;
	FB* next=NULL;
	FB* before = NULL;
};

FB* Init() {
	FB* w = new FB;
	FB* h = new FB;

	int now=0;
	int i=0;

	while (now < 128) {
		for (now; now < 128; now++) {
			if (Memory[now] == 0) {
				w->startAddr = now;
				break;
			}
		}

		for (now; now < 128; now++) {
			if (Memory[now] != 0||now==127) {
				w->len = now - (w->startAddr);
				w->FBid=i++;
				break;
			}
		}
		if (i == 1) {
			h = w;
		}
		FB* m = new FB;
		m->before = w;
		w->next = m;
		w = m;
		now++;
	}
	
	return h;
}

void PrintMemory() {
	cout << "\n当前内存状态:" << endl;
	cout << "----------------------------------" << endl;
	cout << "StartAddr      Length      Status" << endl;
	cout << "----------------------------------" << endl;

	int now = 0;
	int end = 0;
	int sAddr;
	int status;

	while (now < 128) {
		if (Memory[now] == 0) {
			status = 0;
		}
		else {
			status = Memory[now];
		}
		now++;
		sAddr = now - 1;
		for (now; now < 128; now++) {
			if (Memory[now] != status) {
				end++;
				break;
			}
			end++;
		}
		string s;
		if (status == 0) {
			s = "Free";
		}
		else {
			s = "Allocated";
		}
		cout << sAddr << "\t\t" << end - sAddr << "\t   " << s << endl;
	}

}

void PrintFreeBlocks(FB* h) {
	cout << "\n空闲的内存块:" << endl;
	FB* w = h;
	cout << "----------------------------------" << endl;
	cout << "StartAddr       Length       FreeBlockID" << endl;
	cout << "----------------------------------" << endl;
	while (w->next != NULL) {
		cout << w->startAddr << "\t\t" << w->len << "\t\t" << w->FBid << endl;
		w = w->next;
	}
}

FB* Load(int len,FB* h) {
	FB* w=h;//工作结点,从链首开始
	num++;
	while(w->next!=NULL){
		if (len < w->len) {
			for (int i = w->startAddr; i < w->startAddr + len; i++) {
				Memory[i] = num;
			}
			w->startAddr = w->startAddr + len;
			w->len = w->len - len;
			return h;
		}
		if (len == w->len) {
			for (int i = w->startAddr; i < w->startAddr + len; i++) {
				Memory[i] = num;
			}
			w->next->before = w->before;//删去该空闲块
			w = w->next;
			h = w;
			while (w->next!=NULL) {
				w->FBid--;
				w = w->next;
			}
			return h;
		}
		w = w->next;
	}
	
	return h;
}

FB* Release(int start,FB* h) {
	FB* w = h;
	int i = start;
	num--;
	int PCBnum=Memory[start];
	while (Memory[i] == PCBnum) {
		Memory[i] = 0;
		i++;//最后i会指向释放完以后的下一个地址
	}

	//如果释放的内存块前面是空的
	if (Memory[start - 1] == 0&&Memory[i]!=0) {
		//定位到前面的FB
		while (w->next != NULL) {
			if ((w->startAddr + w->len) == start ) {
				w->len = i - w->startAddr;
				return h;
			}
			w = w->next;
		}
	}
	//如果释放的内存块后面是空的
	if (Memory[i] == 0&&Memory[start-1]!=0) {
		while (w->next != NULL) {
			if (w->startAddr == i) {
				w->startAddr = start;
				w->len = w->len+i-start;
				return h;
			}
			w = w->next;
		}
	}
	//前后都是空的
	if (Memory[start - 1] == 0 && Memory[i] == 0) {
		while (w->next != NULL) {
			if ((w->startAddr + w->len) == start) {
				w->len = w->next->len + w->next->startAddr - w->startAddr;
				w->next = w->next->next;//删除释放的内存块后面的那个空闲块
				w->next->before = w;
				w = w->next;
				//更新之后的空闲块ID
				while (w->next != NULL) {
					w->FBid++;
					w = w->next;
				}
				return h;
			}
			w = w->next;
		}
	}
	//前后都不是空的
	if (Memory[start - 1] != 0 && Memory[i] != 0) {
		FB* nfb = new FB;
		nfb->startAddr = start;
		nfb->len = i - start;
		int temp = start-1;
		while (Memory[temp] != 0&& temp!=0) {
			temp--;
		}
		if (temp != 0) {
			while (w->next != NULL) {
				if ((w->startAddr + w->len) == temp+1) {
					nfb->next = w->next;
					w->next->before = nfb;
					nfb->before = w;
					w->next = nfb;
					w = nfb;
					//更新FBid
					while (w->next != NULL) {
						w->FBid = w->before->FBid + 1;
						w = w->next;
					}
					return h;
				}
				w = w->next;
			}
		}
		//要改首结点了呢
		else {
			nfb->FBid = 0;
			nfb->next = h;
			h->before = nfb;
			h = nfb;
			while (w->next != NULL) {
				w->FBid++;
				w = w->next;
			}
			return h;
		}
		
	}
	return h;
}

int main() {
	FB* h = Init();
	int c;
	while (true) {
		PrintMemory();
		PrintFreeBlocks(h);
		cout << "\n\n分配(1) or 释放(0) or 退出(3)?" << endl;
		cin >> c;
		if (c == 1) {
			cout << "大小?" << endl;
			int s;
			cin >> s;
			h=Load(s,h);
		}
		else if(c==0) {
			cout << "释放内存块的首地址?" << endl;
			int s;
			cin >> s;
			h=Release(s,h);
		}
		else if (c == 3) {
			break;
		}
	}
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值