FZU 1893 内存管理

本文介绍了一种内存管理模拟方法,通过最佳适配算法为进程分配内存。详细解释了内存表的结构及操作流程,并提供了一个使用vector实现的示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

E - 内存管理

Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

Description

在为进程动态分配内存时,操作系统必须对其进行管理。一种管理内存的方式是,维护一张记录内存使用情况的表来模拟内存的存储情况,其任一表项可能是以下两种情况之一:一个已分配给进程的内存区或者一个空闲的内存区。表中每一个表项含有以下内容:空闲区或已使用内存区的指示标志、内存大小、指向下一表项的指针。 
一个表项一般有一个前驱表项和一个后继表项(除非这个表项是内存的最底端或最顶端),已使用区表项的前驱表项和后继表项可能是已使用区表项也可能是空闲区表项,而空闲区表项的前驱表项和后继表项只可能是已使用区表项,因为如果两个空闲区表项如果互为相邻的表项,我们就可以将它们合并为一个空闲区表项,内存大小为两个空闲区表项之和。 
当系统创建一个新的进程时,有很多种方法可以用来为新创建的进程分配内存,在这里我们假设已知新进程要占用的内存大小,并只可能给进程分配连续的内存空间。在本题中,我们采用最佳适配算法来分配内存。最佳适配算法搜索整个表,找出够用的最小的空闲区(如有多个,取表中最前的),并将新进程分配在空闲区的顶部,如有剩余内存仍作为空闲区表项,并且为新已使用区表项的下一表项。 
当系统结束一个进程时,在整个表中找到相应的已使用区表项并将其变为空闲区表项。 
你的任务是编写一个程序,来实现这样一个内存管理的过程。在本题中,初始时内存表只有一个内存空闲区表项,且内存大小为100个单位大小。 Input

输入数据第一行为一整数T,表示有T组输入数据。
每组数据每行是一个系统命令,包括“Create”,“Delete”,“Print”,“End”,每条命令后面的参数如下: 
Create:两个整数i和size,i表示新进程的进程号,i>0,size表示新进程需占用的内存大小,size>0,输入保证新进程的进程号与已存在的进程号不同。 
Delete:一个整数i,i>0,表示要结束的进程号。 
Print:无参数。 
End:无参数,不做任何处理,表示系统终止命令。 
注意:输入保证出现的表项个数不超过100个。Output

对于Create命令,如果成功创建新进程,输出一行“Create process i of size s successfully!”,其中i为新进程的进程号,s为新进程占用的内存大小;如果无足够大小的内存空闲区,输出一行“No enough memory!”。 
对于Delete命令,如果成功结束进程,输出一行“Delete process i of size s successfully!”,其中i为结束进程的进程号,s为该进程占用的内存大小;如果内存中无该进程,输出一行“No such process!”。 
对于Print命令,将内存表从表头开始按顺序输出,每行输出一个表项,进程表项格式为“P 进程号 内存大小”,空闲区表项格式为“H 内存大小”。 
对于End命令,不做任何处理,终止程序。Sample Input

2

Create 1 30

Create 2 20

Create 3 30

Print

Create 4 100

Delete 4

Delete 2

Print

Delete 3

Print

End

Create 1 100

Print

End

Sample Output

Create process 1 of size 30 successfully!

Create process 2 of size 20 successfully!

Create process 3 of size 30 successfully!

P 1 30

P 2 20

P 3 30

H 20

No enough memory!

No such process!

Delete process 2 of size 20 successfully!

P 1 30

H 20

P 3 30

H 20

Delete process 3 of size 30 successfully!

P 1 30

H 70

Create process 1 of size 100 successfully!

P 1 100


其实这道题就根据题目意思一步一步来写就可以了,简单是简单,但是很烦,细节要注意,尤其是关于头和尾的操作要单独算,也不要忘记把相邻的空内存合并,发现很多人都用链表写的,表示还没学哇,就用vector写了一个,应该还是很好理解的。

代码如下:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
char str[100];
int arr[105];
struct node
{
	int id;
	char state;
	int size;
};
vector<node> G;
int main()
{
	int t, tmp, msize, flag, a, j;
	scanf("%d", &t);	
	while(t--)
	{
		node in;
		in.id = 0;
		in.state = 'H';
		in.size = 100;
		G.push_back(in);
		while(~scanf("%s", str))
		{
			if(strcmp(str, "End") == 0) break;
			
			if(strcmp(str, "Create") == 0) 
			{
				scanf("%d%d", &in.id, &in.size);
				tmp = 0,  msize = 200;
				for(int i = 0; i < G.size(); i++)
				{
					if(G[i].state == 'H')
					{
						if(G[i].size >= in.size && G[i].size < msize)
						{
							msize = G[i].size;
							tmp = i;
						}
					}
				}
				if(msize == 200) printf("No enough memory!\n");
				else
				{
					in.state = 'P';
					G[tmp].size -= in.size;
					G.insert(G.begin()+tmp, in);
					if(G[tmp].size == 0)
					{
						G.erase(G.begin() + tmp);
					}
					printf("Create process %d of size %d successfully!\n", in.id, in.size);
				}
			}
			
			if(strcmp(str, "Print") == 0)
			{
				for(int i = 0; i < G.size(); i++)
				{
					if(G[i].state == 'P')
						printf("%c %d %d\n", G[i].state, G[i].id, G[i].size);
					else
						if(G[i].size != 0)
						printf("H %d\n", G[i].size);
				}
			}
			
			if(str[0] == 'D')
			{
				flag = 1;
				scanf("%d", &a);
				for(j = 0; j < G.size(); j++)
				{
					if(G[j].id == a && G[j].state == 'P')
					{
						printf("Delete process %d of size %d successfully!\n", a, G[j].size);
						a = 0;
						G[j].state = 'H';
						if(j == 0)
						{
							if(G[1].state == 'H')
							{
								G[0].size += G[1].size;
								G.erase(G.begin() + 1);
							}	
						}
						else
						{
							if(j == G.size())
							{
								if(G[j-1].state == 'H')
								{
									G[j-1].size += G[j].size;
									G.erase(G.begin() + j);
								}	
							}
							else
							{
								if(G.size() > 1)
								{
									if(G[j-1].state == 'H')
									{
										G[j].size += G[j-1].size;
										G.erase(G.begin()+j-1);
										flag = 0;
									}
									if(G[j+flag].state == 'H')
									{
										G[j+flag-1].size += G[j+flag].size;
										G.erase(G.begin()+j+flag);
									}
								}
								break;
							}
						}
					}
				}
				if(a != 0) printf("No such process!\n");
			}
		}
		G.clear();		
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值