Variable partition management realizes dynamic application and release of memory (c language)

Variable partition management realizes dynamic application and release of memory

Variable partition management is an implementation method of continuous storage management. This method divides partitions according to job size. The time, size and location of the division are dynamic. It is a dynamic partitioning method.

topic

Use variable partition management to realize dynamic application and release of memory, limit the maximum number of partitions and storage space size, and display partition information after each operation. When applying for memory, select a free area that meets the requirements and allocate a partition; when the requirements are not met or the limit on the number of partitions is exceeded, an allocation failure is prompted; when the memory is released, the corresponding memory area is reclaimed and merged into a new one Free area.

Ideas

It is still somewhat difficult for us to implement the underlying memory allocation mechanism. Here we only use the C language to implement the mechanism that simulates variable partition management. In order to simulate this mechanism, you mainly need to implement the following:

  • Representation of partitions and partition table data structures
  • Partition search and allocation algorithm
  • Partition release and partition merging operations

1. Data definition

The linked list structure is used to store partition information. Here, two linked lists, free and occupied, can be used to store free partitions and allocated partitions respectively. Of course, if you don't want the operation to be so complicated, you can also use a linked list to do it directly. You only need to add an additional attribute when defining the node to determine whether the partition is free.

#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;

2. Search and allocation of partitions

When a user makes a memory request, the linked list needs to be searched to find a partition that meets the requirements and allocate it to the user. There are many algorithms for partition allocation, as follows:

  1. First (first time) adaptation allocation algorithm:
    Search in order from the beginning of the chain, and start allocation when you find the first partition that meets the requirements. This algorithm requires free partition chains to be linked in increasing address order.
  2. The next time (the first time in the cycle) adaptive allocation algorithm:
    each time it does not search from the beginning of the chain, but starts from the next partition of the free partition found last time.
  3. Optimal adaptive allocation algorithm:
    search sequentially from the beginning of the chain each time, and allocate the smallest partition that can meet the requirements. Free partitions are usually arranged in ascending order of size.
  4. Worst-fit allocation algorithm:
    Search sequentially from the beginning of the chain each time, and allocate the largest partition that can meet the requirements.
  5. Fast adaptive allocation algorithm
    sets up separate linked lists for free areas of frequently used lengths.
    A simple and efficient first (first) adaptation allocation algorithm is used here.
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;
	}	

3. Partition release and partition merging

Partition release mainly considers the following four situations:

  1. Left and right are not idle
    | Process A | Process X | Process B |
  2. Right partition free
    | process A | process X | free |
  3. Left partition free
    | free | process X | process B |
  4. The partitions on both sides are free
    |idle|process X|idle|
    The code is as follows:
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++;
	}

4. Others

The above has completed the main part of the mechanism for simulating variable partition management. Just organize the interactive operation process appropriately.
Reference code is given here:

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();//这是一个简单的遍历链表的函数
	}
}

Guess you like

Origin blog.csdn.net/qq_51330798/article/details/125134050