在可变分区管理方式下采用最先适应算法实现主存分配和实现主存回收

一、算法基本思想

  可变分区方式是按作业需要的主存空间大小来分割分区的。当要装入一个作业时,根据作业需要的主存量查看是否有足够的空闲空间,若有,则按需要量分割一个分区分配给该作业;若无,则作业不能装入。随着作业的装入、撤离,主存空间被分成许多个分区,有的分区被作业占用,而有的分区是空闲的。为了说明哪些区是空闲的,可以用来装入新作业,必须要有一张空闲区说明表。当有一个新作业要求装入主存时,必须查空闲区说明表,从中找出一个足够大的空闲区。有时找到的空闲区可能大于作业需要量,这时应把原来的空闲区变成两部分:一部分分给作业占用;另一部分又成为一个较小的空闲区。为了尽量减少由于分割造成的空闲区,而尽量保存高地址部分有较大的连续空闲区域,以利于大型作业的装入。为此,在空闲区说明表中,把每个空闲区按其地址顺序登记,即每个后继的空闲区其起始地址总是比前者大。为了方便查找还可使表格“紧缩”,总是让“空表目”栏集中在表格的后部。采用最先适应算法(顺序分配算法)分配主存空间。按照作业的需要量,查空闲区说明表,顺序查看登记栏,找到第一个能满足要求的空闲区。当空闲区大于需要量时,一部分用来装入作业,另一部分仍为空闲区登记在空闲区说明表中。由于本实验是模拟主存的分配,所以把主存区分配给作业后并不实际启动装入程序装入作业,而用输出“分配情况”来代替。

分配的流程图:
在这里插入图片描述
当一个作业执行结束撤离时,作业所占的区域应该 归还,归还的区域如果与其它空闲区相邻,则应合成一个较 大的空闲区,登记在空闲区说明表中。例如,在提示(1) 中列举的情况下,如果作业2撤离,归还所占主存区域时, 应与上、下相邻的空闲区一起合成一个大的空闲区登记在空闲区说明表中。归还时的流程图如下:
在这里插入图片描述

二、程序所用的数据结构和符号说明

函数FIRST_FIT()提供功能选择页面,函数init()初始化空闲区信息,在该步中已经装入三个作业,函数input()装入作业分配内存,函数finish()撤销作业回收内存,函数merge()实现相邻空闲区合并操作,函数sort()让空闲区按照起始地址从小到大排序,output1和output2实现相关输出展示。

三、具体实现

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <iomanip>

#define n 100					// 最大空闲区个数
using namespace std;

int p_num = 4;					// 作业个数
int num = 2;					// 空闲区个数

struct
{
	char name[20];
	int address;
	int length;
	int flag;
} free_table[n], work_table[n], temp;

void sort()		// 空闲区按起始地址从小到大排序
{
	int i;
	for (i = 0; i < num - 1; i++)
		for (int j = 0; j < num - i - 1; j++)
			if (free_table[j].address > free_table[j + 1].address)
			{
				temp = free_table[j];
				free_table[j] = free_table[j + 1];
				free_table[j + 1] = temp;
			}

	for (i = 0; i < p_num - 1; i++)
		for (int j = 0; j < p_num - i - 1; j++)
			if (work_table[j].address > work_table[j + 1].address)
			{
				temp = work_table[j];
				work_table[j] = work_table[j + 1];
				work_table[j + 1] = temp;
			}
}


void merge()		// 扫描空闲区若前后有相邻空闲区则合并
{
	for (int i = 0; i < num-1; i++)
	{
		if (free_table[i].address + free_table[i].length == free_table[i+1].address)
		{
			if(!free_table[i].flag && !free_table[i+1].flag)
			{
				free_table[i].length += free_table[i+1].length;
				for (int j = i+1; j < num-1; j++)
						free_table[j] = free_table[j + 1];
				i--;
				num--;
			}
		}
	}
}


void output1()		// 输出空闲区表信息
{
	cout << "空闲区表:" << endl << "    起始地址" << "\t" << "长度" << "\t"<<"状态" <<endl;
	for (int i = 0; i < num; i++)
		cout  << "\t" << free_table[i].address << "\t" << free_table[i].length << "\t" <<free_table[i].flag << endl;
		cout << endl ;
}

void output2()		// 输出已分配区表信息
{
	cout << "已分配区表:" << endl << "    起始地址" <<"\t" << "长度" <<"\t" <<"状态" << "\t" <<"占用作业" <<endl;
	for (int i = 0; i < p_num; i++)
		cout << "\t" <<work_table[i].address << "\t" << work_table[i].length << "\t" << work_table[i].flag <<"\t" <<work_table[i].name << endl;
		cout << endl;
}

// 初始化空闲区信息
void init()
{
	cout <<"------------最先适应算法------------" << endl ;

    work_table[0].address =0;
    work_table[0].length =10;
    work_table[0].flag = 1 ;
    strcpy(work_table[0].name, "操作系统");

	work_table[1].address = 10;
    work_table[1].length= 4;
	work_table[1].flag = 1;
	strcpy(work_table[1].name, "1");

	work_table[2].address = 32;
    work_table[2].length= 96;
	work_table[2].flag = 1;
	strcpy(work_table[2].name, "2");

	work_table[3].address = 14;
    work_table[3].length= 12;
	work_table[3].flag = 1;
	strcpy(work_table[3].name, "3");

	free_table[0].address = 26;
	free_table[0].length =6;
	free_table[0].flag = 0;

	free_table[1].address = 128;
	free_table[1].length =896;
	free_table[1].flag = 0;

	sort();
	merge();
	cout << endl ;
    sort();

	output1();
	output2();
}

// 装入作业,分配内存
void input()
{
	int i, length;
	char name[20];
	cout << "输入作业序号: ";
	gets(name);
	cout << "输入作业大小: ";
	cin >> length;
	fflush(stdin);

	for (i = 0; i < num; i++)
	{
		if(!free_table[i].flag)
		{
			if (length < free_table[i].length)
			{
				work_table[p_num].address = free_table[i].address;
				free_table[i].length = free_table[i].length - length;
				free_table[i].address = free_table[i].address + length;
				strcpy(work_table[p_num].name, name);
				work_table[p_num].flag = 1;
				work_table[p_num].length = length;
				p_num++;
				break;
			}
			else if (length == free_table[i].length)
			{
				strcpy(work_table[p_num].name, name);
				work_table[p_num].flag = 1;
				work_table[p_num].address = free_table[i].address;
				work_table[p_num].length = free_table[i].length;
				p_num++;
				for(int j=i; j<num; j++)
				{
					free_table[j]=free_table[j+1];
				}
				num--;
				break;
			}
		}
	}
	if (i == num)
	{
		cout << endl << "无合适空闲区,不能为作业分配内存!" << endl;
		return;
	}
	sort();
	output1();
	output2();
}

// 撤消作业,回收内存
void finish()
{
	char name[20];
	int i;
	cout <<"输入作业序号:";
	gets(name);
	fflush(stdin);
	bool flag = 0;
	for (i = 0; i < p_num; i++)
	{
		if (!strcmp(name, work_table[i].name))
		{
			free_table[num] = work_table[i];
			free_table[num].flag = 0;
			num++;

			sort();
			merge();

			for(int j = i; j < p_num; j++)
				work_table[j] = work_table[j+1];
			p_num--;
			flag = 1;
			break;
		}
	}
	if (!flag)
		cout << endl <<"没有此作业,重新输入!";
	output1();
	output2();
}

void FIRST_FIT()
{
	init();
	while (1)
	{
		int c;
		cout << "1.装入作业" << endl << "2.撤销作业" << endl << "3.退出" <<"请输入你的选择:";
		cin >> c;
		cout <<endl;
		fflush(stdin);
		if (c == 1)
			input();
		else if (c == 2)
			finish();
        else break;
	}
}

int main(void)
{
	FIRST_FIT();
	return 0;
}

四、实验结果

假设主存中已装入三个作业,且形成两个空闲区,确定空闲区说明表的初值。现有一个需要主存量为6K的作业4申请装入主存;然后作业3撤离;再作业2撤离。请你为它们进行主存分配和回收,把空闲区说明表的初值以及每次分配或回收后的变化显示出来或打印出来。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 16
    点赞
  • 134
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是一个简单的可变分区管理代码,包括最佳适应算法最先适应算法和最差适应算法: ``` #include <stdio.h> #define MAX_MEM_SIZE 1024 typedef struct { int start; int end; int size; int status; // 0 - free, 1 - allocated } Partition; Partition partitions[MAX_MEM_SIZE]; int numOfPartitions = 0; // 初始化分区表 void initializePartitions() { Partition p = {0, MAX_MEM_SIZE - 1, MAX_MEM_SIZE, 0}; partitions[numOfPartitions++] = p; } // 打印分区表 void printPartitions() { printf("Partition Table:\n"); printf("Start\tEnd\tSize\tStatus\n"); for (int i = 0; i < numOfPartitions; i++) { printf("%d\t%d\t%d\t%s\n", partitions[i].start, partitions[i].end, partitions[i].size, partitions[i].status == 0 ? "Free" : "Allocated"); } printf("\n"); } // 最佳适应算法 int bestFit(int size) { int index = -1; int minSize = MAX_MEM_SIZE + 1; for (int i = 0; i < numOfPartitions; i++) { if (partitions[i].status == 0 && partitions[i].size >= size && partitions[i].size < minSize) { index = i; minSize = partitions[i].size; } } return index; } // 最先适应算法 int firstFit(int size) { for (int i = 0; i < numOfPartitions; i++) { if (partitions[i].status == 0 && partitions[i].size >= size) { return i; } } return -1; } // 最差适应算法 int worstFit(int size) { int index = -1; int maxSize = -1; for (int i = 0; i < numOfPartitions; i++) { if (partitions[i].status == 0 && partitions[i].size >= size && partitions[i].size > maxSize) { index = i; maxSize = partitions[i].size; } } return index; } // 分配内存 void allocateMemory(int size, int algorithm) { int index = -1; switch (algorithm) { case 1: // 最佳适应算法 index = bestFit(size); break; case 2: // 最先适应算法 index = firstFit(size); break; case 3: // 最差适应算法 index = worstFit(size); break; default: printf("Invalid algorithm!\n"); return; } if (index != -1) { Partition p = partitions[index]; p.status = 1; p.size = size; partitions[index] = p; if (p.start + size <= p.end) { Partition newPartition = {p.start + size, p.end, p.end - (p.start + size) + 1, 0}; partitions[numOfPartitions++] = newPartition; } printf("Memory allocated successfully!\n"); } else { printf("Memory allocation failed!\n"); } } // 释放内存 void freeMemory(int start) { for (int i = 0; i < numOfPartitions; i++) { Partition p = partitions[i]; if (p.start == start && p.status == 1) { p.status = 0; partitions[i] = p; printf("Memory freed successfully!\n"); return; } } printf("Memory free failed!\n"); } int main() { initializePartitions(); int choice = 0; do { printf("1. Print partition table\n"); printf("2. Allocate memory\n"); printf("3. Free memory\n"); printf("4. Exit\n"); printf("Enter your choice: "); scanf("%d", &choice); switch (choice) { case 1: printPartitions(); break; case 2: printf("Enter memory size to allocate: "); int size; scanf("%d", &size); printf("Enter algorithm (1 - best fit, 2 - first fit, 3 - worst fit): "); int algorithm; scanf("%d", &algorithm); allocateMemory(size, algorithm); break; case 3: printf("Enter memory start address to free: "); int start; scanf("%d", &start); freeMemory(start); break; case 4: printf("Exiting program.\n"); break; default: printf("Invalid choice!\n"); break; } } while (choice != 4); return 0; } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值