可变分区管理实现内存的动态申请与释放(c语言)

可变分区管理实现内存的动态申请与释放

可变分区管理是属于连续存储管理的实现方法,这种方法按照作业大小划分分区,划分的时间、大小和位置都是动态的,是一种动态分区方法。

题目

以可变分区管理实现内存的动态申请与释放,限定最大分区数和存储空间大小,每次操作后显示分区信息。当申请内存时,从中选取满足要求的空闲区,并划出一个分区;当不满足要求或超出分区数限制时,提示分配失败;当释放内存时,回收相应内存区,并合并成一个新的空闲区。

思路

由我们去实现底层的内存分配机制还是有些困难的,这里只是用c语言实现模拟可变分区管理的这种机制。为了模拟这种机制主要需要实现以下内容:

  • 分区和分区表数据结构的表示
  • 分区的查找与分配算法
  • 分区的释放与合并分区的操作

一、数据定义

采用链表的结构存储分区信息,这里可以用空闲和占用两个链表分别存储空闲分区和已分配的分区。当然,如果不想操作那么复杂的话也可以直接用一条链表搞定,只需要在节点定义时多加一个属性来判断分区是否空闲即可。

#define MaxParts 5//定义分区最大数
#define Memaxsize 1024//定义内存大小


typedef struct Part//分区信息
{
	int startAddress;//开始地址
	int length;//分区长度
	bool freee;//是否空闲
	struct Part *next;//下一个分区
}Part;

Part partFirst={0,Memaxsize,true,NULL};//初始化分区链表首项

typedef struct Distribution//分配结果
{
	bool give;//是否获得分区
	Part *part;//分区信息
	int errorType;//错误类型 1 分区数过多 2 无足够大的分区
}Distribution;

二、分区的查找与分配

当由用户提出内存申请时,需要对链表进行查找,找到符合要求的分区分配给用户,分区分配有很多种算法,如下:

  1. 最先(首次)适应分配算法:
    从链首顺序查找,找到第一个满足要求的分区即可开始分配。该算法要求空闲分区链以地址递增顺序链接。
  2. 下次(循环首次)适应分配算法:
    每次不从链首查找,而是从上次找到的空闲分区的下一个分区开始查找。
  3. 最优适应分配算法:
    每次从链首顺序查找,分配能满足要求的最小分区。 通常将空闲分区按照大小从小到大排列。
  4. 最坏适应分配算法:
    每次从链首顺序查找,分配能满足要求的最大分区。
  5. 快速适应分配算法
    为经常用到的长度的空闲区设置单独的链表。
    这里采用简单高效的最先(首次)适应分配算法。
for(Part *temp = &partFirst;temp != NULL;temp = temp->next)//遍历内存分区表
	{
		if (temp->freee && temp->length > length)//找到足够大的分区
		{
			if (countPart + 1 > MaxParts) //已经达到最大分区数目,拒绝分配
			{
				errorType = 1;
				break;
			}
			else //可以分配
				countPart++;
				
			temp->freee = false;//将分区标记为已分配
			int tempLength = temp->length;
			temp->length = length;//分区长度为申请长度
			
			Part * tempNext = temp->next;//新建一个分区节点插入到当前分区节点之后
			tempNext = (Part *)malloc(sizeof(Part));
			tempNext->startAddress=temp->startAddress + temp->length;
			tempNext->length=tempLength - length;
			tempNext->freee=true;
			tempNext->next=temp->next;
			temp->next=tempNext;//这些步骤主要是为分割之后剩余的部分新建一个分区插入到分区链中,其中步骤不再赘述注释
			
			disPart = temp;
			dised = true;
			break;
		}
		else if (temp->freee && temp->length == length)//大小相等直接修改空闲值 
		{
			temp->freee = false;//这种情况不需要分割分区,直接分配
			disPart = temp;
			dised = true;
			break;
		}
		if(temp->next==NULL)//没有找到满足大小的分区,返回错误信息
			errorType = 2;
	}	

三、分区释放与分区合并

分区释放主要考虑以下四种情况:

  1. 左右不空闲
    | 进程A | 进程X | 进程B |
  2. 右分区空闲
    | 进程A | 进程X | 空闲 |
  3. 左分区空闲
    | 空闲 | 进程X | 进程B |
  4. 两侧分区空闲
    | 空闲 | 进程X | 空闲 |
    代码如下:
for(Part *temp = &partFirst;temp != NULL;temp = temp->next)//遍历找释放分区的前一个分区
	{
		if (i+1 == n && temp->next != NULL) 
		{
			if (temp->next->next != NULL && temp->next->next->freee == true) //后一个为空闲
			{
				if (temp->freee) //前后都为空闲,合并三个分区
				{
					Part *center = temp->next;
					Part *right = temp->next->next;
					Part *tempNext = temp->next->next->next;
					temp->length += temp->next->length + temp->next->next->length;
					temp->next = tempNext;
					free(center);
					center=NULL;
					free(right);
					right=NULL;
				}
				else //后面一个为空闲,合并两个分区
				{
					Part *right = temp->next->next;
					Part *tempNext = temp->next->next->next;
					temp->next->length += temp->next->next->length;
					temp->next->next = tempNext;
					temp->next->freee = true;
					free(right);
					right=NULL;
				}
			}
			else //后一个不为空闲
			{
				if (temp->freee) //前一个为空闲,合并两个分区
				{
					Part *center = temp->next;
					Part *tempNext = temp->next->next;
					temp->length += temp->next->length;
					temp->next = tempNext;
					free(center);
					center=NULL;
				}
				else//前后都不为空,只释放分区
					temp->next->freee = true;
			}
			freee = true;
			break;
		}
		else if(n==1)//特例判断,释放第一项,仅观察其后一分区是否为空
		{
			if(temp->next->freee)//释放分区并合并
			{
				Part *right = temp->next;
				Part *tempNext = temp->next->next;
				temp->length += temp->next->length;
				temp->next = tempNext;
				temp->freee = true;
				free(right);
				right=NULL;
			}
			else//只释放分区
				temp->freee = true;
			freee = true;
			break;
		}
		i++;
	}

四、其他

上述已经完成了模拟实现可变分区管理的机制主体部分,适当组织一下交互操作流程即可。
这里给出参考代码:

void Menu() 
{
	int selected;
	int value;
	Distribution ret;
	bool quit = false;
	while (!quit)
	{
		printf("可变分区存储管理\n");
		printf("1、申请内存\n");
		printf("2、释放内存\n");
		printf("3、退	出\n");
		scanf("%d",&selected);
		switch (selected)
		{
			case 1:	printf("请输入申请内存大小:\n");
					scanf("%d",&value);
					ret = requestMe(value);
					if (ret.give)
					{
						printf("\n分配成功.\n");
					}
					else 
					{
						printf("\n分配失败.\n");
						switch(ret.errorType)
						{
							case 1:
									printf("%s.\n", "分区数达到限制");
									break;
							case 2:
									printf("%s.\n", "没有足够大的分区可以分配");
									break;
							case 0:default:break;
						}
						
					}
					break;
			case 2:
					printf("请输入要释放的分区序号:\n");
					scanf("%d",&value);
					freeMe(value);
					break;
			case 3:
					quit = true;
					break;
					default:
					break;
		}
		if(!quit)
			showMe();//这是一个简单的遍历链表的函数
	}
}

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 这个问题是关于存储管理方案的内存分配和回收的。在B'C语言中,可变分区存储管理方案是一种常见的方式,它通常会将内存分配为不同大小的分区,并在需要时将分配给进程,然后当进程不再需要时,释放已分配的分区。回收内存是非常重要的,因为不及时释放内存可能会导致内存泄漏和系统崩溃。 ### 回答2: C语言可变分区存储管理方式主要是指在程序运行时,根据实际的内存需求动态地划分内存空间,从而提高程序的运行效率和存储效率。 内存分配:在C语言中,内存分配常常使用malloc()函数来实现。该函数可以指定需要分配的内存大小,在申请内存时,系统会在堆中分配一块连续的内存空间,并将该内存空间的起始地址返回给程序。程序员可以根据需要将该内存空间用于存储数据。 如果程序在运行中需要更多的内存空间,则可以通过realloc()函数重新分配已有的内存空间,或者使用calloc()函数动态地分配空间。这样既可以有效节省内存空间,又能够满足程序的需要。 内存回收:在使用完内存后,程序需要将内存空间释放回系统,以便其他程序可以使用该内存。为了实现内存回收,C语言提供了free()函数。该函数可以释放已经分配的内存空间,并将该空间返回给系统,以便其他程序可以使用。 需要注意的是,程序在使用内存时应该避免出现内存泄漏的情况,即程序在使用一些动态分配的内存空间后,却没有将其释放回系统,导致内存空间的浪费。 总之,C语言可变分区存储管理方式以其高效、灵活的特点,成为了程序开发中常用的技术之一。程序员应该针对实际的需求选择最合适的内存分配方式,并合理地使用内存回收功能,以提高程序的性能和稳定性。 ### 回答3: 可变分区存储管理方式是一种内存分配和回收的方法,适用于不同大小的程序。在c语言中,可变分区存储管理方式可以通过malloc和free两个函数来实现内存分配过程使用malloc函数,该函数根据传入的参数大小来分配相应大小的内存。通常,当一个程序需要动态地使用内存时,程序员需要请求系统分配一段内存,以便程序可以使用它。malloc函数会返回一个void类型的指针,该指针指向分配的内存空间的起始地址。此外,malloc函数还会进行内存对齐的操作,以确保分配的内存对齐到特定大小的边界。 内存释放过程使用free函数,该函数用于回收malloc函数分配的内存。当程序不再需要使用某段内存时,程序员必须调用free函数释放该段内存,以便该内存可以被重新分配给其他程序使用。该函数接受一个指向分配内存的指针作为参数,该指针必须是由malloc函数返回的。 在可变分区存储管理方式中,程序员需要特别注意内存分配和回收的顺序。如果程序员没有正确地分配和回收内存,则可能会导致内存泄漏或内存损坏,从而影响程序的运行和稳定性。同时,如果使用不当,malloc函数可能会分配过多的内存,导致内存的浪费或内存不足的问题。 总之,c语言可变分区存储管理方式提供了一种灵活和高效的内存管理方法,可以使程序更加灵活地处理内存,并避免出现内存泄漏或内存冲突的问题。足够的注意和谨慎是确保正确使用可变分区存储管理方式的关键。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值