动态分区分配算法(First Fit,Next Fit,Best Fit,Worst Fit)

一、动态分区分配算法的背景

为了能将用户程序装入内存,必须为它分配一定大小的内存空间。连续分配方式是最早出现的一种存储器分配方式, 曾被广泛应用于上世纪60~ -80 年代的OS中,该分配万式为个用户程序分配 一个连续的内存空间, 即程序中代码或数据的逻辑地址相邻,体现在内存空间分配时物理地址的相邻。连续分配方式可分为四类:单一连续分配、固定分区分配、动态分区分配以及动态可重定位分区分配算法四种方式,其中动态分区分配算法就是此实验的实验对象。
动态分区分配又称为可变分区分配,它是根据进程的实际需要,动态地为之分配内存空间。在实现动态分区分配时,将涉及到分区分配中所用的数据结构、分区分配算法和分区的分配与回收操作这样三方面的问题。
动态分区分配又称为可变分区分配,它是根据进程的实际需要,动态地为之分配内存空间。在实现动态分区分配时,将涉及到分区分配中所用的数据结构、分区分配算法和分区的分配与回收操作这样三方面的问题。

二、四种分配算法原理

1.首次适应算法(First Fit)

将空闲分区链以地址递增的顺序连接;在进行内存分配时,从链首开始顺序查找,直到找到一块分区的大小可以满足需求时,按照该作业的大小,从该分区中分配出内存,将剩下的空闲分区仍然链在空闲分区链中。
在这里插入图片描述

2.循环首次适应算法(Next Fit)

分配内存时不是从链首进行查找可以分配 内存的空闲分区,而是从上一次分配内存的空闲分区的下一个分区开始查找,直到找到可以为该进程分配内存的空闲分区;
在这里插入图片描述

3.最佳适应算法(Best Fit)

将空闲分区链中的空闲分区按照空闲分区由小到大的顺序排序,从而形成空闲分区链。每次从链首进行查找合适的空闲分区为作业分配内存,这样每次找到的空闲分区是和作业大小最接近的,所谓“最佳”。
在这里插入图片描述

4.最坏适应算法(Worst Fit)

与最佳适应算法刚好相反,将空闲分区链的分区按照从大到小的顺序排序形成空闲分区链,每次查找时只要看第一个空闲分区是否满足即可。
在这里插入图片描述

三、四种算法过程记录

动态内存信息:
分区个数:5
各分区首址:0 50 190 340 530
各分区大小:130 70 140 80 20

1.首次适应算法(First Fit)

在这里插入图片描述

2.循环首次适应算法(Next Fit)
在这里插入图片描述

3.最佳适应算法(Best Fit)
在这里插入图片描述

4.最坏适应算法(Worst Fit)
在这里插入图片描述

四、算法的优劣比较

1.首次适应算法(First Fit)

优点:高址部分的大的空闲分区得到保留,为大作业的内存分配创造了条件;
缺点:
(1)每次都是优先利用低址部分的空闲分区,造成低址部分产生大量的外碎片。
(2)每次都是从低址部分查找,使得查找空闲分区的开销增大;

2.循环首次适应算法(Next Fit)

优点:
(1)使得空闲分区分布更加均匀;
(2)空闲分区的查找开销小;
缺点:高址部分的大空闲分区被分小,使得大作业进入无法分配内存;

3.最佳适应算法(Best Fit)

优点:第一次找到的空闲分区是大小最接近待分配内存作业大小的;
缺点:产生大量难以利用的外部碎片。

4.最坏适应算法(Worst Fit)

优点:效率高,分区查找方便;
缺点:当小作业把大空闲分区分小了,那么,大作业就找不到合适的空闲区。

五、代码实现

Partition.h

#pragma once
#include <iostream>
#include <fstream>
#include<string>
#include<vector>
#include<functional>
#include<cstdlib>
#include<map>
#include<set>
using namespace std;
typedef struct//分区
{
	static int PartitionNum;//分区数量 
	int m_PartitionId;//分区首地容量址
	int m_PartitionSize;//分区
	int m_BlockId;//空白分区首地址
}Partition;

typedef struct//进程控制块
{
	static int PCBNum;//进程数量
	string m_PidName;//进程名称
	int m_PidSize;//进程大小
}PCB;

void ReadData();//读入数据
void Display1();
void Display_Partition();
void Display();//输出分区完后各个分区的状态
void Display_PCB();//显示进程的状态
void FirstFit();//首次适应算法
void NextFit();//循环首次适应算法
void BestFit();//最佳适应算法
void WorstFit();//最坏适应算法

Partition.cpp

#include" Partition.h"

int Partition::PartitionNum = 0;
int PCB::PCBNum = 0;
Partition* partition;
PCB* pcb;
int MIN;


void ReadData()//读入数据
{
	ifstream readData;
	readData.open("data.txt");

	readData >> Partition::PartitionNum;//读入分区数量
	partition = new Partition[Partition::PartitionNum];//开空间

	for (int i = 0; i < Partition::PartitionNum; i++)//读入分区起始地址
	{
		readData >> partition[i].m_PartitionId;
		partition[i].m_BlockId = partition[i].m_PartitionId;
	}
	for (int i = 0; i < Partition::PartitionNum; i++)//读入分区大小
	{
		readData >> partition[i].m_PartitionSize;
	}

	//readData >> PCB::PCBNum;//读入进程数量
	//pcb = new PCB[PCB::PCBNum];

	//for (int i = 0; i < PCB::PCBNum; i++)//读入进程名称
	//{
	//	readData >> pcb[i].m_PidName;
	//}

	//for (int i = 0; i < PCB::PCBNum; i++)//读入进程大小
	//{
	//	readData >> pcb[i].m_PidSize;
	//}
	//readData.close();
}

void FirstFit()//首次适应算法
{
	bool flag = false;
	int i, j;
	string choose;
	ReadData();
	//cout << "输入MIN:";
	//cin >> MIN;
	//Display_PCB();
	do
	{
		Display_Partition();
		pcb = (PCB*)realloc(pcb, sizeof(PCB)*(PCB::PCBNum + 1));
		cout << "输入进程名称:";
		cin >> pcb[PCB::PCBNum - 1].m_PidName;
		cout << "输入进程大小:";
		cin >> pcb[PCB::PCBNum - 1].m_PidSize;

		i = PCB::PCBNum - 1;

		for (j = 0; j < Partition::PartitionNum; j++)
		{
			if (pcb[i].m_PidSize <= partition[j].m_PartitionSize)
			{
				partition[j].m_PartitionSize -= pcb[i].m_PidSize;
				partition[j].m_BlockId += partition[j].m_PartitionSize;
				if (partition[j].m_PartitionSize <= MIN)
				{
					partition[j].m_PartitionSize = 0;
				}
				flag = true;
				break;
			}
		}
		if (flag)
		{
			flag = false;
			cout << "进程" << pcb[i].m_PidName << "分配到分区" << partition[j].m_PartitionId << endl;
		}
		else
		{
			cout << "进程" << pcb[i].m_PidName << "分配失败!" << endl;
		}
		Display1();
		cout << "继续分配按Y" << endl;
		cin >> choose;

	} while (choose == "Y");
}
void NextFit()//循环首次适应算法
{
	int pos = 0;
	bool flag = false;
	int i, j;
	string choose;
	ReadData();
	//Display_PCB();
	/*cout << "输入MIN:";
	cin >> MIN;*/
	do
	{

		Display_Partition();
		pcb = (PCB*)realloc(pcb, sizeof(PCB)*(PCB::PCBNum+1));
		cout << "输入进程名称:";
		cin >> pcb[PCB::PCBNum - 1].m_PidName;
		cout << "输入进程大小:";
		cin >> pcb[PCB::PCBNum - 1].m_PidSize;
		i = PCB::PCBNum - 1;

		for (j = pos;; j++)
		{
			if (pos >= PCB::PCBNum)
			{
				pos = 0;
			}
			if (pcb[i].m_PidSize <= partition[j].m_PartitionSize)
			{
				partition[j].m_PartitionSize -= pcb[i].m_PidSize;
				partition[j].m_BlockId += partition[j].m_PartitionSize;
				if (partition[j].m_PartitionSize <= MIN)
				{
					partition[j].m_PartitionSize = 0;
				}
				flag = true;
				pos = j + 1;
				if (pos == PCB::PCBNum)
				{
					pos = 0;
				}
				break;
			}
		}
		if (flag)
		{
			flag = false;
			cout << "进程" << pcb[i].m_PidName << "分配到分区" << partition[j].m_PartitionId << endl;
		}
		else
		{
			cout << "进程" << pcb[i].m_PidName << "分配失败!" << endl;
		}
		Display1();
		cout << "继续分配按Y" << endl;
		cin >> choose;

	} while (choose == "Y");

}
void BestFit()//最佳适应算法
{
	int pos = 0;
	bool flag = false;
	int i, j;
	multimap<int, Partition*> m;
	multimap<int, Partition*>::iterator ip;
	string choose;
	ReadData();
	//Display_PCB();
	/*cout << "输入MIN:";
	cin >> MIN;*/
	do
	{
		Display_Partition();
		pcb = (PCB*)realloc(pcb, sizeof(PCB)*(PCB::PCBNum + 1));
		cout << "输入进程名称:";
		cin >> pcb[PCB::PCBNum - 1].m_PidName;
		cout << "输入进程大小:";
		cin >> pcb[PCB::PCBNum - 1].m_PidSize;
		i = PCB::PCBNum - 1;

		m.clear();
		for (j = 0; j < Partition::PartitionNum; j++)//按从小带大排序
		{
			m.insert(make_pair(partition[j].m_PartitionSize, partition + j));
		}

		for (ip = m.begin(); ip != m.end();)
		{
			if (pcb[i].m_PidSize <= ip->first)
			{
				ip->second->m_PartitionSize -= pcb[i].m_PidSize;
				ip->second->m_BlockId += ip->second->m_PartitionSize;
				/*if (ip->second->m_PartitionSize <= MIN)
				{
				ip->second->m_PartitionSize = 0;
				}*/
				flag = true;
				break;
			}
			else
			{
				ip++;
			}
		}
		if (flag)
		{
			flag = false;
			cout << "进程" << pcb[i].m_PidName << "分配到分区" << ip->second->m_PartitionId << endl;
		}
		else
		{
			cout << "进程" << pcb[i].m_PidName << "分配失败!" << endl;
		}
		Display();
		cout << "继续分配按Y" << endl;
		cin >> choose;

	} while (choose == "Y");
}
void WorstFit()//最坏适应算法
{
	int pos = 0;
	bool flag = false;
	int i, j;
	multimap<int, Partition*, greater<int>> m;
	multimap<int, Partition*>::iterator ip = m.begin();
	string choose;
	ReadData();
	//Display_PCB();
	/*cout << "输入MIN:";
	cin >> MIN;*/
	do
	{
		Display_Partition();
		pcb = (PCB*)realloc(pcb, sizeof(PCB)*(PCB::PCBNum + 1));
		cout << "输入进程名称:";
		cin >> pcb[PCB::PCBNum - 1].m_PidName;
		cout << "输入进程大小:";
		cin >> pcb[PCB::PCBNum - 1].m_PidSize;
		i = PCB::PCBNum - 1;

		m.clear();
		for (j = 0; j < Partition::PartitionNum; j++)//按从大到小排序
		{
			m.insert(make_pair(partition[j].m_PartitionSize, partition + j));
		}

		for (ip = m.begin(); ip != m.end();)
		{
			if (pcb[i].m_PidSize <= ip->first)
			{
				ip->second->m_PartitionSize -= pcb[i].m_PidSize;
				ip->second->m_BlockId += ip->second->m_PartitionSize;
				/*if (ip->second->m_PartitionSize <= MIN)
				{
				ip->second->m_PartitionSize = 0;
				}*/
				flag = true;
				break;
			}
			else
			{
				ip++;
			}
		}
		if (flag)
		{
			flag = false;
			cout << "进程" << pcb[i].m_PidName << "分配到分区" << ip->second->m_PartitionId << endl;
		}
		else
		{
			cout << "进程" << pcb[i].m_PidName << "分配失败!" << endl;
		}
		Display();
		cout << "继续分配按Y" << endl;
		cin >> choose;

	} while (choose == "Y");
}
void Display()
{
	int i;
	set<int> s;
	for (i = 0; i < Partition::PartitionNum; i++)
	{
		s.insert(partition[i].m_PartitionSize);
	}

	cout << "空白分区链:";
	for (auto& e : s)
	{
		cout << e << "->";
	}
	cout << "NULL";
	cout << endl;
}

void Display1()
{
	int i;
	map<int, Partition*> m;
	for (i = 0; i < Partition::PartitionNum; i++)
	{
		m.insert(make_pair(partition[i].m_PartitionId, partition + i));
	}

	cout << "空白分区链:";
	for (auto& e : m)
	{
		if (e.second->m_PartitionSize != 0)
		{
			cout << e.second->m_PartitionSize << "->";
		}
	}
	cout << "NULL";
	cout << endl;
}
void Display_Partition()
{
	cout << endl << "分区起始地址 ";
	for (int i = 0; i < Partition::PartitionNum; i++)
	{
		printf("%-d  ", partition[i].m_PartitionId);
	}
	cout << endl << "分区大小:   ";
	for (int i = 0; i < Partition::PartitionNum; i++)
	{

		printf("%-d  ", partition[i].m_PartitionSize);

	}
	cout << endl << endl;
}

void Display_PCB()
{
	cout << endl << "进程id:  ";
	for (int i = 0; i < PCB::PCBNum; i++)
	{
		printf("%3s  ", pcb[i].m_PidName.c_str());
	}
	cout << endl << "进程大小:";
	for (int i = 0; i < PCB::PCBNum; i++)
	{
		printf("%3d  ", pcb[i].m_PidSize);
	}
	cout << endl << endl;
}

Main.cpp

#include"Partition.h"

int main()
{
	int choose;
	while (1)
	{
		cout << "请选择实现的算法:" << endl;
		cout << "*****  1 - 首次适应算法     *****" << endl;
		cout << "*****  2 - 循环首次适应算法 *****" << endl;
		cout << "*****  3 - 最佳适应算法     *****" << endl;
		cout << "*****  4 - 最坏适应算法     *****" << endl;
		cout << "*****  0 - 结束             *****" << endl;
		cout << "输入你的选择 : ";
		cin >> choose;
		switch (choose)
		{
			
			case 0:exit(0); break;
			case 1:FirstFit(); break;
			case 2:NextFit(); break;
			case 3:BestFit(); break;
			case 4:WorstFit(); break;
			default:cout << "请输入正确的序号:" << endl;
		}
	}
    system("pause");
    return 0;
}

(488条消息) 动态分区分配算法(First Fit,Next Fit,Best Fit,Worst Fit)_托马斯.杨的博客-CSDN博客_动态分区分配算法

  • 12
    点赞
  • 153
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
动态分区分配算法是一种内存管理算法,用于在程序运行时为进程分配内存空间。其中常用的动态分区分配算法有以下几种: 1. 首次适应算法(First Fit):从内存的起始位置开始搜索,找到第一个能够满足进程大小的空闲分区进行分配。 2. 最佳适应算法Best Fit):从所有空闲分区中找到最小的能够满足进程大小的空闲分区进行分配。 3. 最坏适应算法Worst Fit):从所有空闲分区中找到最大的能够满足进程大小的空闲分区进行分配。 下面是一个使用C++实现首次适应算法的示例代码: ```c++ #include <iostream> using namespace std; struct Node { int start; //空闲分区的起始地址 int size; //空闲分区的大小 Node* next; //指向下一个空闲分区的指针 }; Node* head = nullptr; //空闲分区链表的头指针 void init(int start, int size) { head = new Node{ start, size, nullptr }; } void allocate(int processId, int size) { Node* p = head; Node* prev = nullptr; while (p != nullptr) { if (p->size >= size) { //找到了满足进程大小的空闲分区 Node* q = new Node{ p->start, size, nullptr }; //创建一个新的进程分区 if (prev != nullptr) { prev->next = q; //更新前一个空闲分区的next指针 } else { head = q; //更新头指针 } p->start += size; //修改原空闲分区的起始地址和大小 p->size -= size; cout << "Process " << processId << " allocated " << size << " bytes from " << q->start << endl; return; } prev = p; p = p->next; } cout << "Process " << processId << " cannot be allocated " << size << " bytes" << endl; } void deallocate(int processId) { Node* p = head; Node* prev = nullptr; while (p != nullptr) { if (p->start == processId) { //找到了该进程分配的分区 if (prev != nullptr) { prev->next = p->next; //更新前一个空闲分区的next指针 } else { head = p->next; //更新头指针 } cout << "Process " << processId << " deallocated " << p->size << " bytes from " << p->start << endl; delete p; //释放该进程分配的分区 return; } prev = p; p = p->next; } cout << "Process " << processId << " does not have any allocated space" << endl; } void print() { Node* p = head; while (p != nullptr) { cout << "Free space: " << p->start << " - " << p->start + p->size - 1 << ", " << p->size << " bytes" << endl; p = p->next; } } int main() { init(0, 1024); //初始化空闲分区链表 allocate(1, 100); //为进程1分配100个字节的空间 allocate(2, 200); //为进程2分配200个字节的空间 print(); //输出空闲分区链表 deallocate(1); //释放进程1分配的空间 print(); //输出空闲分区链表 return 0; } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值