Simulation of dynamic partition allocation algorithm (the most complete one in the whole network)

Simulation of Experiment 2 Dynamic Partition Allocation Algorithm

2.1 Simulation of the first adaptation algorithm

1. Experimental purpose and requirements

1. The purpose of the experiment
1) Deepen the understanding of the memory management process of the operating system
2) Master the basic application of memory allocation algorithms

2. Experimental environment (tools, configuration, etc.)

1. Hardware requirements: a computer.
2. Software requirements: Windows operating system, using any programming language, such as c, c++, Java, etc.

3. Experimental content

1. Algorithm idea: first adaptation algorithm: connect the free partition chains in the order of increasing addresses; when performing memory allocation, search sequentially from the beginning of the chain until a partition is found whose size can meet the requirements, according to the size of the job, Allocate memory from this partition, and link the remaining free partitions to the free partition chain.
2. Memory state initialization: the user dynamically inputs the number of blank partitions, and sets the size of the blank partitions. Here I input 5 blank partitions, the sizes of which are: 100, 200, 300, 400, 500 (unit: KB). The result of setting the initial state of the memory is shown in the figure below:

insert image description here

Figure 1 Memory state initialization
3. Allocate memory and check the memory status: job A applies for 120KB of memory, job B applies for 80KB of memory, job C applies for 320KB of memory, job D applies for 410KB of memory, and job E applies for 100KB of memory. The allocation results are shown in the figure below , in line with the expected results:
insert image description here
Figure 2 memory allocation (1)
insert image description here insert image description here
Figure 2 memory allocation (2)
insert image description here
Figure 3 results after allocation

4. Merge the fragmented space: Enter 4 to merge the allocated memory into the fragmented space, and then enter 3 to check the memory status, the result is shown in the figure below:
insert image description here

Figure 4 Merge fragmented space

5. Release memory: Enter 2, choose to release the memory with partition number 1, the result is shown in the figure below, after release, the memory with partition number 1 is in an idle state, which meets the expected result
insert image description here

Figure 5 Before release

insert image description here

Figure 6 After release

6. Analysis: It can be clearly seen from the above simulation that the algorithm tends to preferentially utilize the free area of ​​the low-address part of the memory, thereby retaining a large free partition of the high-address part, creating conditions for the memory allocation of large jobs. But every time, the free partitions in the low-address part are preferentially used, resulting in a large number of fragments in the low-address part, and at the same time, the search is performed from the low-address part every time, which increases the overhead of searching for free partitions.

The code looks like this:

#include<iostream>
#include<stdlib.h>
#include<windows.h>
using namespace std;

#define Free 0 //空闲状态
#define Busy 1 //已用状态
#define OK 1    //完成
#define ERROR 0 //出错
#define MAX_length 2048 //定义最大主存信息2048KB
#define Min_Size 10  //规定的不可分割的剩余分区的大小 
int flag;//标志位 
//函数声明 
int myMalloc();//内存分配
int free(int); //内存回收
int First_fit(int);//首次适应算法
void printNode();//查看分配
int Init();//空闲分区的设置
int Combination();//合并碎片空间 


typedef struct Kongxian //定义一个空闲区说明表结构
{
    
        
    char name[30] ;
	long size;   //分区大小
	long address; //分区地址
	int state;   //空闲标志  
}Elem;

typedef struct LinkNode// 双向链表存储结构
{
    
    
	Elem data;
	struct LinkNode *prior; //前趋指针
	struct LinkNode *next;  //后继指针
}LinkNode, *LinkList;

LinkList block_first; //头结点
LinkList block_last;  //尾结点
LinkNode *pn ;        //循环首次适应算法中的指针 

void menu(){
    
         //打印操作界面 
	 printf("\n"); 
		printf("\t\t\t\t    *****   首次适应算法的动态分区分配方式模拟   *****  \n");
		printf("\t\t\t\t   ┌───────────────────────────────────────────-┐\n");
		printf("\t\t\t\t   │                                            │\n");
		printf("\t\t\t\t   │                 1. 申请内存                │\n");
		printf("\t\t\t\t   │                                            │\n");
		printf("\t\t\t\t   │                 2. 释放内存                │\n");
		printf("\t\t\t\t   │                                            │\n");
		printf("\t\t\t\t   │                 3. 查看内存情况            │\n");
		printf("\t\t\t\t   │                                            │\n");
		printf("\t\t\t\t   │                 4. 合并碎片空间            │\n");
		printf("\t\t\t\t   │                                            │\n");
		printf("\t\t\t\t   │                 5.退出                     │\n");
		printf("\t\t\t\t   └────────────────────────────────────────────┘\n");
		printf("\t\t\t\t\t\t  请您选择(1-5):\t");		//打印想要进行的操作
}

int Init()//初始化内存状态设置(空闲分区的设置) 
{
    
    
	int Free_num; //空闲分区的个数 
	block_first = (LinkList)malloc(sizeof(LinkNode));
	block_last = (LinkList)malloc(sizeof(LinkNode));
	block_first->prior = NULL;
	block_first->next = block_last;
	cout << "请输入空闲分区数目:";
	cin  >> Free_num ;
	int Size[Free_num];
	printf("\n请分别输入这%d空闲分区大小(单位KB):\n",Free_num ); 
	for(int i = 0; i < Free_num; i++) 
	{
    
    
	    cin >> Size[i];
	    if(Size[i] <= Min_Size)	{
    
    
	    	i--;
	    	cout << "\n输入错误,请重输!\n";
		}
	    int temp = 0;
		temp = temp + Size[i];	
		if(temp >= MAX_length)	{
    
    
	    	i--;
	    	cout << "\n输入错误,请重输!\n";
		}
	}
	LinkList p = block_first;
	for(int i = 0; i < Free_num; i++)
	{
    
       
		LinkList temp = (LinkList)malloc(sizeof(LinkNode));
		temp->data.size = Size[i];
	    temp->data.state = Free;
	    if(p == block_first)
	      temp->data.address = 0;
	    else
	    temp->data.address = p->data.address + p->data.size;
	    temp->prior =p;
		p->next = temp;
		p = p->next; 
		
	}
	block_last = p;
	block_last->next = NULL;
	pn = block_first->next; 
	return OK;
}


int myMalloc()//分配主存
{
    
    
	int request = 0;
	cout << "请输入需要分配的主存大小(单位:KB):"<<endl;
	cin >> request;
	if (request<0 || request == 0)
	{
    
    
		cout << "分配大小不合适,请重试!" << endl;
		return ERROR;
	}

	if (First_fit(request) == OK) cout << "分配成功!" << endl;
		else cout << "内存不足,分配失败!" << endl;
		return OK;	
}


int First_fit(int request)//首次适应算法
{
    
    
	//为申请作业开辟新空间且初始化
	LinkList temp = (LinkList)malloc(sizeof(LinkNode));
	temp->data.size = request;
	temp->data.state = Busy;
    cout << "请输入作业名:";
	cin >>temp->data.name  ;
	cout <<endl; 
	LinkNode *p = block_first->next;
	while (p)
	{
    
    
		if (p->data.state == Free && p->data.size - request <= Min_Size && p->data.size - request >= 0) //有大小恰好合适的空闲块
		{
    
    
			p->data.state = Busy;
			for(int i = 0; i < 10; i++){
    
    
				p->data.name[i] = temp->data.name[i];
			}
			return OK;
			break;
		}
		if (p->data.state == Free && p->data.size - request > Min_Size) //有空闲块能满足需求且有剩余
		{
    
    
			temp->prior = p->prior;
			temp->next = p;
			temp->data.address = p->data.address;
			p->prior->next = temp;
			p->prior = temp;
			p->data.address = temp->data.address + temp->data.size;
			p->data.size -= request;
			return OK;
			break;
		}
		p = p->next;
	}
	return ERROR;
}

int free(int flag)//主存回收
{
    
    
	LinkNode *p = block_first;
	for (int i = 0; i <= flag; i++)
		if (p != NULL)
			p = p->next;
		else
			return ERROR;

	p->data.state = Free;
    if(p == block_last){
    
    
    	if (p->prior != block_first && p->prior->data.state == Free )//与前面的空闲块相连
	{
    
    
		p->prior->data.size += p->data.size;//空间扩充,合并为一个
		p = p->prior;
		p->next = NULL;
		block_last  = p;
	}
	}
	else{
    
    
	
	if (p->prior != block_first && p->prior->data.state == Free )//与前面的空闲块相连
	{
    
    
		p->prior->data.size += p->data.size;//空间扩充,合并为一个
		p->prior->next = p->next;//去掉原来被合并的p
		p->next->prior = p->prior;
		p = p->prior;
	}
	if (p->next != block_last && p->next->data.state == Free )//与后面的空闲块相连
	{
    
    
		p->data.size += p->next->data.size;//空间扩充,合并为一个
		p->next->next->prior = p;
		p->next = p->next->next;
	}
	if (p->next == block_last && p->next->data.state == Free )//与最后的空闲块相连
	{
    
    
		p->data.size += p->next->data.size;
		p->next = NULL;
	}
}
	return OK;
}

int Combination()     //实现紧凑,合并碎片 
{
    
       
	LinkNode *p = block_first->next;
	int size = 0;
	while(p){
    
                                         
      	if(p->data.state ==Free && p != block_last)    //去除空闲分区 
     	{
    
    
		  size =size + p->data.size ;
		  p->next->prior =p->prior ;
		  p->prior->next = p->next ; 
        }
        else{
    
    
        	p->data.address = p->data.address - size;   //改变地址 
		}
		p = p->next; 
	}
	if(block_last->data.state == Free){
    
         //实现最后合并空闲分区 
	   block_last->data.size += size; 
	}
	else if(size != 0){
    
                         //将所有空闲分区合并放在最后一个分区后面 
		LinkList temp = (LinkList)malloc(sizeof(LinkNode));
		block_last->next =temp;
		temp->prior = block_last;
		temp->next = NULL;
		temp->data.size  = size;
		temp->data.address = block_last->data.address + block_last->data.size ;
		block_last = temp;  
		temp->data.state = Free;
	}
	pn = block_first->next; 
	if(size == 0)   //判断是否有碎片 
	{
    
    
		return ERROR; 
	}
	return OK;
}

void printNode()//显示内存分配情况
{
    
    
	int num = 0;
	printf("                        内存情况                        \n"); 
	cout << "======================================================\n\n";
	LinkNode *p = block_first->next;
	cout << "分区号\t起始地址\t分区大小\t状态\t作业名\n\n";
	while (p)
	{
    
    
		cout << "  " << num++ << "\t";
		cout << "  " << p->data.address << "\t\t";
		cout << " " << p->data.size << "KB\t\t";
		if (p->data.state == Free) {
    
    
			cout << "空闲\n\n";
		}
		else {
    
    
		cout << "已分配\t";
		cout  <<"  "<<p->data.name <<"\n\n";
	    }
	
		
		p = p->next;
	}
	cout << "======================================================\n\n";
}

void Operate(){
    
    
	int choice;  //操作选择标记
	while (1)
	{
    
    
		menu();
		scanf("%d",&choice);
		if (choice == 1) myMalloc(); // 分配内存
		else if (choice == 2)  // 内存回收
		{
    
    
			int flag;
			cout << "请输入您要释放的分区号:"<<endl;
			cin >> flag;
			free(flag);
		}
		else if (choice == 3) printNode();
		else if(choice == 4)
		{
    
    
			if(Combination() == 0){
    
    
				cout<<"无需合并碎片空间!"<<endl;
			}
			else{
    
    
				cout<<"成功合并碎片!"<<endl;
			}
		}
		else if (choice == 5) break; //退出
		else //输入操作有误
		{
    
    
			cout << "输入有误,请重试!" << endl;
			continue;
		}
	}
}

int main()//主函数
{
    
       
    system("color 5E");
	Init(); //初始化内存状态 
	Operate();
	return 0; 
}


2.2 Simulation of best fit algorithm

1. Experimental results and analysis

1. Algorithm idea: sort the free partitions in the free partition chain according to the order of the free partitions from small to large, thus forming a free partition chain. Each time a suitable free partition is searched from the head of the chain to allocate memory for the job, so that the free partition found each time is the closest to the size of the job, the so-called "best".
2. Memory state initialization: the user dynamically inputs the number of blank partitions, and sets the size of the blank partitions. Here I input 5 blank partitions, the sizes of which are: 100, 200, 300, 400, 500 (unit: KB). The result of setting the initial state of the memory is shown in the figure below:
insert image description here

Figure 1 Initial state of memory
3. Allocate memory and check the memory status: job A applies for 120KB of memory, job B applies for 80KB of memory, job C applies for 320KB of memory, job D applies for 410KB of memory, and job E applies for 100KB of memory. The allocation results are shown in the figure below and meet the expected results

insert image description here

Figure 4 Allocation results

4. Merge fragmented space: Enter 4 to merge the memory allocated above to merge the fragmented space, and then enter 3 to check the memory status, the result is shown in the figure below:
insert image description here

Figure 5 merged fragment space
5. Release memory: Enter 2, choose to release the memory with partition number 1, the result is shown in the figure below, after release, the memory with partition number 1 is in an idle state, which meets the expected result

6. Analysis: It can be clearly seen from the above simulation that the algorithm requires all free partitions to form a chain of free partitions in order of their capacity from small to large, which speeds up the search. The free area that meets the conditions found for the first time must be the best. The remaining space of each split is always the smallest, reducing the size of external fragments generated. In isolation, it seems to be the best, but not necessarily macroscopically. And from the perspective of space utilization, the NF algorithm does make the best use of everything, but each division leaves external fragments that are difficult to use, which reduces the search efficiency.

The code looks like this:

#include<iostream>
#include<stdlib.h>
#include<windows.h>
using namespace std;

#define Free 0 //空闲状态
#define Busy 1 //已用状态
#define OK 1    //完成
#define ERROR 0 //出错
#define MAX_length 2048 //定义最大主存信息2048KB
#define Min_Size 10  //规定的不可分割的剩余分区的大小 
int flag;//标志位  
//函数声明
int myMalloc();//内存分配
int free(int); //内存回收
int Best_fit(int);//最佳适应算法
void printNode();//查看分配
int Init();//空闲分区的设置
int Combination();//合并碎片空间  

typedef struct FreeArea //定义一个空闲区说明表结构
{
    
        
    char name[30] ;
	long size;   //分区大小
	long address; //分区地址
	int state;   //空闲标志  
}Elem;

typedef struct LinkNode// 双向链表存储结构
{
    
    
	Elem data;
	struct LinkNode *prior; //前趋指针
	struct LinkNode *next;  //后继指针
}LinkNode, *LinkList;


LinkList block_first; //头结点
LinkList block_last;  //尾结点
LinkNode *pn ;        //循环首次适应算法中的指针 

void menu(){
    
         //打印操作界面 
	 printf("\n"); 
		printf("\t\t\t\t    *****   最佳适应算法的动态分区分配方式模拟   *****  \n");
		printf("\t\t\t\t   ┌───────────────────────────────────────────-┐\n");
		printf("\t\t\t\t   │                                            │\n");
		printf("\t\t\t\t   │                 1. 申请内存                │\n");
		printf("\t\t\t\t   │                                            │\n");
		printf("\t\t\t\t   │                 2. 释放内存                │\n");
		printf("\t\t\t\t   │                                            │\n");
		printf("\t\t\t\t   │                 3. 查看内存情况            │\n");
		printf("\t\t\t\t   │                                            │\n");
		printf("\t\t\t\t   │                 4. 合并碎片空间            │\n");
		printf("\t\t\t\t   │                                            │\n");
		printf("\t\t\t\t   │                 5.退出                     │\n");
		printf("\t\t\t\t   └────────────────────────────────────────────┘\n");
		printf("\t\t\t\t\t\t  请您选择(1-5):\t");		//打印想要进行的操作
}

int Init()//初始化内存状态设置(空闲分区的设置) 
{
    
    
	int Free_num; //空闲分区的个数 
	block_first = (LinkList)malloc(sizeof(LinkNode));
	block_last = (LinkList)malloc(sizeof(LinkNode));
	block_first->prior = NULL;
	block_first->next = block_last;
	cout << "请输入空闲分区数目:";
	cin  >> Free_num ;
	int Size[Free_num];
	printf("\n请分别输入这%d空闲分区大小(单位KB):\n",Free_num ); 
	for(int i = 0; i < Free_num; i++) 
	{
    
    
	    cin >> Size[i];
	    if(Size[i] <= Min_Size)	{
    
    
	    	i--;
	    	cout << "\n输入错误,请重输!\n";
		}
	    int temp = 0;
		temp = temp + Size[i];	
		if(temp >= MAX_length)	{
    
    
	    	i--;
	    	cout << "\n输入错误,请重输!\n";
		}
	}
	LinkList p = block_first;
	for(int i = 0; i < Free_num; i++)
	{
    
       
		LinkList temp = (LinkList)malloc(sizeof(LinkNode));
		temp->data.size = Size[i];
	    temp->data.state = Free;
	    if(p == block_first)
	      temp->data.address = 0;
	    else
	    temp->data.address = p->data.address + p->data.size;
	    temp->prior =p;
		p->next = temp;
		p = p->next; 
		
	}
	block_last = p;
	block_last->next = NULL;
	pn = block_first->next; 
	return OK;
}


int myMalloc()//分配主存
{
    
    
	int request = 0;
	cout << "请输入需要分配的主存大小(单位:KB):"<<endl;
	cin >> request;
	if (request<0 || request == 0)
	{
    
    
		cout << "分配大小不合适,请重试!" << endl;
		return ERROR;
	}
	if (Best_fit(request) == OK) cout << "分配成功!" << endl;
		else cout << "内存不足,分配失败!" << endl;
		return OK;
}


int Best_fit(int request)//最佳适应算法
{
    
    
	int ch; //记录最小剩余空间
	LinkList temp = (LinkList)malloc(sizeof(LinkNode));
	temp->data.size = request;
	temp->data.state = Busy;
	LinkNode *p = block_first->next;
	LinkNode *q = NULL; //记录最佳插入位置
    cout << "请输入作业名:";
	cin >>temp->data.name  ;
	while (p) //初始化最小空间和最佳位置
	{
    
    
		if (p->data.state == Free && (p->data.size >= request))
		{
    
    
			if (q == NULL)
			{
    
    
				q = p;
				ch = p->data.size - request;
			}
			else if (q->data.size > p->data.size)
			{
    
    
				q = p;
				ch = p->data.size - request;
			}
		}
		p = p->next;
	}

	if (q == NULL) return ERROR;//没有找到空闲块
	else if (q->data.size - request <= Min_Size)
	{
    
    
		q->data.state = Busy;
		for(int i = 0; i < 10; i++){
    
    
				q->data.name[i] = temp->data.name[i];
			}
		return OK;
	}
	else
	{
    
    
		temp->prior = q->prior;
		temp->next = q;
		temp->data.address = q->data.address;
		q->prior->next = temp;
		q->prior = temp;
		q->data.address += request;
		q->data.size = ch;
		return OK;
	}
	return OK;
}

int free(int flag)//主存回收
{
    
    
	LinkNode *p = block_first;
	for (int i = 0; i <= flag; i++)
		if (p != NULL)
			p = p->next;
		else
			return ERROR;

	p->data.state = Free;
    if(p == block_last){
    
    
    	if (p->prior != block_first && p->prior->data.state == Free )//与前面的空闲块相连
	{
    
    
		p->prior->data.size += p->data.size;//空间扩充,合并为一个
		p = p->prior;
		p->next = NULL;
		block_last  = p;
	}
	}
	else{
    
    
	
	if (p->prior != block_first && p->prior->data.state == Free )//与前面的空闲块相连
	{
    
    
		p->prior->data.size += p->data.size;//空间扩充,合并为一个
		p->prior->next = p->next;//去掉原来被合并的p
		p->next->prior = p->prior;
		p = p->prior;
	}
	if (p->next != block_last && p->next->data.state == Free )//与后面的空闲块相连
	{
    
    
		p->data.size += p->next->data.size;//空间扩充,合并为一个
		p->next->next->prior = p;
		p->next = p->next->next;
	}
	if (p->next == block_last && p->next->data.state == Free )//与最后的空闲块相连
	{
    
    
		p->data.size += p->next->data.size;
		p->next = NULL;
	}
}
	return OK;
}

int Combination()     //实现紧凑,合并碎片 
{
    
       
	LinkNode *p = block_first->next;
	int size = 0;
	while(p){
    
                                         
      	if(p->data.state ==Free && p != block_last)    //去除空闲分区 
     	{
    
    
		  size =size + p->data.size ;
		  p->next->prior =p->prior ;
		  p->prior->next = p->next ; 
        }
        else{
    
    
        	p->data.address = p->data.address - size;   //改变地址 
		}
		p = p->next; 
	}
	if(block_last->data.state == Free){
    
         //实现最后合并空闲分区 
	   block_last->data.size += size; 
	}
	else if(size != 0){
    
                         //将所有空闲分区合并放在最后一个分区后面 
		LinkList temp = (LinkList)malloc(sizeof(LinkNode));
		block_last->next =temp;
		temp->prior = block_last;
		temp->next = NULL;
		temp->data.size  = size;
		temp->data.address = block_last->data.address + block_last->data.size ;
		block_last = temp;  
		temp->data.state = Free;
	}
	pn = block_first->next; 
	if(size == 0)   //判断是否有碎片 
	{
    
    
		return ERROR; 
	}
	return OK;
}

void printNode()//显示主存分配情况
{
    
    
	int num = 0;
	printf("                        内存情况                        \n"); 
	cout << "======================================================\n\n";
	LinkNode *p = block_first->next;
	cout << "分区号\t起始地址\t分区大小\t状态\t作业名\n\n";
	while (p)
	{
    
    
		cout << "  " << num++ << "\t";
		cout << "  " << p->data.address << "\t\t";
		cout << " " << p->data.size << "KB\t\t";
		if (p->data.state == Free) {
    
    
			cout << "空闲\n\n";
		}
		else {
    
    
		cout << "已分配\t";
		cout  <<"  "<<p->data.name <<"\n\n";
	    }
	
		
		p = p->next;
	}
	cout << "======================================================\n\n";
}

void Operate(){
    
    
	int choice;  //操作选择标记
	while (1)
	{
    
    
	    menu();
		scanf("%d",&choice);
		if (choice == 1) myMalloc(); // 分配内存
		else if (choice == 2)  // 内存回收
		{
    
    
			int flag;
			cout << "请输入您要释放的分区号:"<<endl;
			cin >> flag;
			free(flag);
		}
		else if (choice == 3) printNode();
		else if(choice == 4)
		{
    
    
			if(Combination() == 0){
    
    
				cout<<"无需合并碎片空间!"<<endl;
			}
			else{
    
    
				cout<<"成功合并碎片!"<<endl;
			}
		}
		else if (choice == 5) break; //退出
		else //输入操作有误
		{
    
    
			cout << "输入有误,请重试!" << endl;
			continue;
		}
	}
}

int main()//主函数
{
    
       
    system("color 5E");
	Init(); //初始化内存状态 
	Operate();
	return 0; 
}

Simulation of Worst Fit Algorithm

Experimental results and analysis

1. Algorithm idea: Contrary to the best fit algorithm, the partitions of the free partition chain are sorted in descending order to form a free partition chain, and each search only needs to check whether the first free partition is satisfied.
2. Memory state initialization: the user dynamically inputs the number of blank partitions and sets the size of the blank partitions. Here I use to input 5 blank partitions, the sizes of which are: 100, 200, 300, 400, 500 (unit: KB), where The result of setting the initial state of the memory is shown in the figure below:
insert image description here

Figure 1 Memory initialization
3. Allocate memory and check the memory status: job S applies for 120KB of memory, job U applies for 80KB of memory, job N applies for 320KB of memory, job R applies for 120KB of memory, and job Y applies for 100KB of memory. The allocation results are shown in the figure below and meet the expected results: ![Insert picture description here](https://img-blog.csdnimg.cn/aa0a7a98f1d943ebab0d556588565a09.png)

insert image description here
insert image description here
3. Merge fragmented space: Enter 4 to merge the allocated memory into fragmented space, and then enter 3 to check the
memory status, the result is shown in the figure below:
insert image description here
4. Release memory: Enter 2, choose to release the memory with partition number 1, the result As shown in the figure below, after release, the memory with partition number 2 is in an idle state, which meets the expected result
insert image description here
insert image description here
6. Analysis: From the above simulation, it can be clearly seen that the worst adaptation algorithm is efficient and easy to find partitions, but when a small job puts If the large free partition is divided into small ones, then the large job cannot find a suitable free partition.
7. Flowchart
insert image description here

#include<iostream>
#include<stdlib.h>
#include<windows.h>
using namespace std;

#define Free 0 //空闲状态
#define Busy 1 //已用状态
#define OK 1    //完成
#define ERROR 0 //出错
#define MAX_length 2048 //定义最大主存信息2048KB
#define Min_Size 10  //规定的不可分割的剩余分区的大小 
int flag;//标志位  
//函数声明
int myMalloc();//内存分配
int free(int); //内存回收
int Worst_fit(int); //最差适应算法
void printNode();//查看分配
int Init();//空闲分区的设置
int Combination();//合并碎片空间 

typedef struct FreeArea //定义一个空闲区说明表结构
{
    
        
    char name[30] ;
	long size;   //分区大小
	long address; //分区地址
	int state;   //空闲标志  
}Elem;

typedef struct LinkNode// 双向链表存储结构
{
    
    
	Elem data;
	struct LinkNode *prior; //前趋指针
	struct LinkNode *next;  //后继指针
}LinkNode, *LinkList;


LinkList block_first; //头结点
LinkList block_last;  //尾结点
LinkNode *pn ;        //循环首次适应算法中的指针 

void menu(){
    
         //打印操作界面 
	 printf("\n"); 
		printf("\t\t\t\t    *****   最差适应算法的动态分区分配方式模拟   *****  \n");
		printf("\t\t\t\t   ┌───────────────────────────────────────────-┐\n");
		printf("\t\t\t\t   │                                            │\n");
		printf("\t\t\t\t   │                 1. 申请内存                │\n");
		printf("\t\t\t\t   │                                            │\n");
		printf("\t\t\t\t   │                 2. 释放内存                │\n");
		printf("\t\t\t\t   │                                            │\n");
		printf("\t\t\t\t   │                 3. 查看内存情况            │\n");
		printf("\t\t\t\t   │                                            │\n");
		printf("\t\t\t\t   │                 4. 合并碎片空间            │\n");
		printf("\t\t\t\t   │                                            │\n");
		printf("\t\t\t\t   │                 5.退出                     │\n");
		printf("\t\t\t\t   └────────────────────────────────────────────┘\n");
		printf("\t\t\t\t\t\t  请您选择(1-5):\t");		//打印想要进行的操作
}


int Init()//初始化内存状态设置(空闲分区的设置) 
{
    
    
	int Free_num; //空闲分区的个数 
	block_first = (LinkList)malloc(sizeof(LinkNode));
	block_last = (LinkList)malloc(sizeof(LinkNode));
	block_first->prior = NULL;
	block_first->next = block_last;
	cout << "请输入空闲分区数目:";
	cin  >> Free_num ;
	int Size[Free_num];
	printf("\n请分别输入这%d空闲分区大小(单位KB):\n",Free_num ); 
	for(int i = 0; i < Free_num; i++) 
	{
    
    
	    cin >> Size[i];
	    if(Size[i] <= Min_Size)	{
    
    
	    	i--;
	    	cout << "\n输入错误,请重输!\n";
		}
	    int temp = 0;
		temp = temp + Size[i];	
		if(temp >= MAX_length)	{
    
    
	    	i--;
	    	cout << "\n输入错误,请重输!\n";
		}
	}
	LinkList p = block_first;
	for(int i = 0; i < Free_num; i++)
	{
    
       
		LinkList temp = (LinkList)malloc(sizeof(LinkNode));
		temp->data.size = Size[i];
	    temp->data.state = Free;
	    if(p == block_first)
	      temp->data.address = 0;
	    else
	    temp->data.address = p->data.address + p->data.size;
	    temp->prior =p;
		p->next = temp;
		p = p->next; 
		
	}
	block_last = p;
	block_last->next = NULL;
	pn = block_first->next; 
	return OK;
}


int myMalloc()//分配主存
{
    
    
	int request = 0;
	cout << "请输入需要分配的主存大小(单位:KB):"<<endl;
	cin >> request;
	if (request<0 || request == 0)
	{
    
    
		cout << "分配大小不合适,请重试!" << endl;
		return ERROR;
	}

	if (Worst_fit(request) == OK) cout << "分配成功!" << endl;
		else cout << "内存不足,分配失败!" << endl;
		return OK;	
}


int Worst_fit(int request)//最差适应算法

{
    
    
	int ch; //记录最大剩余空间
	LinkList temp = (LinkList)malloc(sizeof(LinkNode));
	temp->data.size = request;
	temp->data.state = Busy;
	LinkNode *p = block_first->next;
	LinkNode *q = NULL; //记录最佳插入位置
    cout << "请输入作业名:";
	cin >>temp->data.name  ;
	while (p) //初始化最大空间和最佳位置
	{
    
    
		if (p->data.state == Free && (p->data.size >= request))
		{
    
    
			if (q == NULL)
			{
    
    
				q = p;
				ch = p->data.size - request;
			}
			else if (q->data.size < p->data.size)
			{
    
    
				q = p;
				ch = p->data.size - request;
			}
		}
		p = p->next;
	}

	if (q == NULL) return ERROR;//没有找到空闲块
	else if (q->data.size - request <= Min_Size)
	{
    
    
		q->data.state = Busy;
			for(int i = 0; i < 10; i++){
    
    
				q->data.name[i] = temp->data.name[i];
			}
		return OK;
	}
	else
	{
    
    
		temp->prior = q->prior;
		temp->next = q;
		temp->data.address = q->data.address;
		q->prior->next = temp;
		q->prior = temp;
		q->data.address += request;
		q->data.size = ch;
		return OK;
	}
	return OK;
}


int free(int flag)//主存回收
{
    
    
	LinkNode *p = block_first;
	for (int i = 0; i <= flag; i++)
		if (p != NULL)
			p = p->next;
		else
			return ERROR;

	p->data.state = Free;
    if(p == block_last){
    
    
    	if (p->prior != block_first && p->prior->data.state == Free )//与前面的空闲块相连
	{
    
    
		p->prior->data.size += p->data.size;//空间扩充,合并为一个
		p = p->prior;
		p->next = NULL;
		block_last  = p;
	}
	}
	else{
    
    
	
	if (p->prior != block_first && p->prior->data.state == Free )//与前面的空闲块相连
	{
    
    
		p->prior->data.size += p->data.size;//空间扩充,合并为一个
		p->prior->next = p->next;//去掉原来被合并的p
		p->next->prior = p->prior;
		p = p->prior;
	}
	if (p->next != block_last && p->next->data.state == Free )//与后面的空闲块相连
	{
    
    
		p->data.size += p->next->data.size;//空间扩充,合并为一个
		p->next->next->prior = p;
		p->next = p->next->next;
	}
	if (p->next == block_last && p->next->data.state == Free )//与最后的空闲块相连
	{
    
    
		p->data.size += p->next->data.size;
		p->next = NULL;
	}
}
	return OK;
}

int Combination()     //实现紧凑,合并碎片 
{
    
       
	LinkNode *p = block_first->next;
	int size = 0;
	while(p){
    
                                         
      	if(p->data.state ==Free && p != block_last)    //去除空闲分区 
     	{
    
    
		  size =size + p->data.size ;
		  p->next->prior =p->prior ;
		  p->prior->next = p->next ; 
        }
        else{
    
    
        	p->data.address = p->data.address - size;   //改变地址 
		}
		p = p->next; 
	}
	if(block_last->data.state == Free){
    
         //实现最后合并空闲分区 
	   block_last->data.size += size; 
	}
	else if(size != 0){
    
                         //将所有空闲分区合并放在最后一个分区后面 
		LinkList temp = (LinkList)malloc(sizeof(LinkNode));
		block_last->next =temp;
		temp->prior = block_last;
		temp->next = NULL;
		temp->data.size  = size;
		temp->data.address = block_last->data.address + block_last->data.size ;
		block_last = temp;  
		temp->data.state = Free;
	}
	pn = block_first->next; 
	if(size == 0)   //判断是否有碎片 
	{
    
    
		return ERROR; 
	}
	return OK;
}

void printNode()//显示内存分配情况
{
    
    
	int num = 0;
	printf("                        内存情况                        \n"); 
	cout << "======================================================\n\n";
	LinkNode *p = block_first->next;
	cout << "分区号\t起始地址\t分区大小\t状态\t作业名\n\n";
	while (p)
	{
    
    
		cout << "  " << num++ << "\t";
		cout << "  " << p->data.address << "\t\t";
		cout << " " << p->data.size << "KB\t\t";
		if (p->data.state == Free) {
    
    
			cout << "空闲\n\n";
		}
		else {
    
    
		cout << "已分配\t";
		cout  <<"  "<<p->data.name <<"\n\n";
	    }
	
		
		p = p->next;
	}
	cout << "======================================================\n\n";
}

void Operate(){
    
    
	int choice;  //操作选择标记
	while (1)
	{
    
    
	    menu();
		scanf("%d",&choice);
		if (choice == 1) myMalloc(); // 分配内存
		else if (choice == 2)  // 内存回收
		{
    
    
			int flag;
			cout << "请输入您要释放的分区号:"<<endl;
			cin >> flag;
			free(flag);
		}
		else if (choice == 3) printNode();
		else if(choice == 4)
		{
    
    
			if(Combination() == 0){
    
    
				cout<<"无需合并碎片空间!"<<endl;
			}
			else{
    
    
				cout<<"成功合并碎片!"<<endl;
			}
		}
		else if (choice == 5) break; //退出
		else //输入操作有误
		{
    
    
			cout << "输入有误,请重试!" << endl;
			continue;
		}
	}
}

int main()//主函数
{
    
       
    system("color 5E");
	Init(); //初始化内存状态 
	Operate();
	return 0; 
}

Simulation of Cycle First Adaptation Algorithm

1. Experimental analysis and results
1. Algorithm idea: When allocating memory, it does not search for free partitions that can allocate memory from the head of the chain, but starts searching from the next partition of the free partition that allocated memory last time until it finds a free partition that can be used for the process. Free partitions for allocated memory.
2. Memory state initialization: the user dynamically inputs the number of blank partitions and sets the size of the blank partitions. Here I use to input 5 blank partitions, the sizes of which are: 100, 200, 300, 400, 500 (unit: KB), where The result of setting the initial state of memory is shown in the figure below:
insert image description here3. Allocate memory and check the memory status: job A applies for 120KB of memory, job B applies for 80KB of memory, job C applies for 320KB of memory, job D applies for 410KB of memory, and job E applies for 100KB of memory. The result is as shown in the figure below, which is in line with the expected result:
insert image description here
insert image description here
insert image description here
insert image description here
4. Merge fragmented space: Enter 4 to merge the allocated memory into the fragmented space, and then enter 3 to check the memory status, the result is as shown in the figure below:
insert image description here
5. Release memory: Enter 2, select Release the memory with partition number 1, and the result is shown in the figure below. After release, the memory with partition number 1 is in an idle state, which meets the expected result

insert image description here
insert image description here
6. Analysis: From the above simulation, it can be clearly seen that the loop first adaptation algorithm makes the distribution of free partitions more uniform, and the search overhead of free partitions is small. However, the large free partition in the high-address part is divided into small ones, making it impossible to allocate memory for large jobs.
7. Flowchart
insert image description here
The code is as follows:

#include<iostream>
#include<stdlib.h>
#include<windows.h>
using namespace std;

#define Free 0 //空闲状态
#define Busy 1 //已用状态
#define OK 1    //完成
#define ERROR 0 //出错
#define MAX_length 2048 //定义最大主存信息2048KB
#define Min_Size 10  //规定的不可分割的剩余分区的大小 
int flag;//标志位 
//函数声明
int myMalloc();//内存分配
int free(int); //内存回收
int Next_fit(int);//循环首次适应算法 
void printNode();//查看分配
int Init();//空闲分区的设置
int Combination();//合并碎片空间 
 
typedef struct FreeArea //定义一个空闲区说明表结构
{
    
        
    char name[30] ;
	long size;   //分区大小
	long address; //分区地址
	int state;   //空闲标志  
}Elem;

typedef struct LinkNode// 双向链表存储结构
{
    
    
	Elem data;
	struct LinkNode *prior; //前趋指针
	struct LinkNode *next;  //后继指针
}LinkNode, *LinkList;


LinkList block_first; //头结点
LinkList block_last;  //尾结点
LinkNode *pn ;        //循环首次适应算法中的指针 

void menu(){
    
         //打印操作界面 
	 printf("\n"); 
		printf("\t\t\t\t    *****   循环首次适应算法的动态分区分配方式模拟   *****  \n");
		printf("\t\t\t\t   ┌───────────────────────────────────────────-┐\n");
		printf("\t\t\t\t   │                                            │\n");
		printf("\t\t\t\t   │                 1. 申请内存                │\n");
		printf("\t\t\t\t   │                                            │\n");
		printf("\t\t\t\t   │                 2. 释放内存                │\n");
		printf("\t\t\t\t   │                                            │\n");
		printf("\t\t\t\t   │                 3. 查看内存情况            │\n");
		printf("\t\t\t\t   │                                            │\n");
		printf("\t\t\t\t   │                 4. 合并碎片空间            │\n");
		printf("\t\t\t\t   │                                            │\n");
		printf("\t\t\t\t   │                 5.退出                     │\n");
		printf("\t\t\t\t   └────────────────────────────────────────────┘\n");
		printf("\t\t\t\t\t\t  请您选择(1-5):\t");		//打印想要进行的操作
}

int Init()//初始化内存状态设置(空闲分区的设置) 
{
    
    
	int Free_num; //空闲分区的个数 
	block_first = (LinkList)malloc(sizeof(LinkNode));
	block_last = (LinkList)malloc(sizeof(LinkNode));
	block_first->prior = NULL;
	block_first->next = block_last;
	cout << "请输入空闲分区数目:";
	cin  >> Free_num ;
	int Size[Free_num];
	printf("\n请分别输入这%d空闲分区大小(单位KB):\n",Free_num ); 
	for(int i = 0; i < Free_num; i++) 
	{
    
    
	    cin >> Size[i];
	    if(Size[i] <= Min_Size)	{
    
    
	    	i--;
	    	cout << "\n输入错误,请重输!\n";
		}
	    int temp = 0;
		temp = temp + Size[i];	
		if(temp >= MAX_length)	{
    
    
	    	i--;
	    	cout << "\n输入错误,请重输!\n";
		}
	}
	LinkList p = block_first;
	for(int i = 0; i < Free_num; i++)
	{
    
       
		LinkList temp = (LinkList)malloc(sizeof(LinkNode));
		temp->data.size = Size[i];
	    temp->data.state = Free;
	    if(p == block_first)
	      temp->data.address = 0;
	    else
	    temp->data.address = p->data.address + p->data.size;
	    temp->prior =p;
		p->next = temp;
		p = p->next; 
		
	}
	block_last = p;
	block_last->next = NULL;
	pn = block_first->next; 
	return OK;
}


int myMalloc()//分配主存
{
    
    
	int request = 0;
	cout << "请输入需要分配的主存大小(单位:KB):"<<endl;
	cin >> request;
	if (request<0 || request == 0)
	{
    
    
		cout << "分配大小不合适,请重试!" << endl;
		return ERROR;
	}
	if (Next_fit(request) == OK) cout << "分配成功!" << endl;
		else cout << "内存不足,分配失败!" << endl;
		return OK;
}

//循环首次适应算法 
int Next_fit(int request){
    
    
 	//为申请作业开辟新空间且初始化
	LinkList temp = (LinkList)malloc(sizeof(LinkNode));
	temp->data.size = request;
	temp->data.state = Busy;
    cout << "请输入作业名:";
	cin >>temp->data.name  ;
	while (pn)
	{
    
    
		if (pn->data.state == Free && pn->data.size - request <=Min_Size && pn->data.size - request >= 0)
		{
    
    //有大小恰好合适的空闲块
			pn->data.state = Busy;
			for(int i = 0; i < 10; i++){
    
    
				pn->data.name[i] = temp->data.name[i];
			}
			return OK;
			break;
		}
		if (pn->data.state == Free && pn->data.size > request + Min_Size)
		{
    
    //有空闲块能满足需求且有剩余
			temp->prior = pn->prior;
			temp->next = pn;
			temp->data.address = pn->data.address;
			pn->prior->next = temp;
			pn->prior = temp;
			pn->data.address = temp->data.address + temp->data.size;
			pn->data.size -= request;
			return OK;
			break;
		}
		pn = pn->next;
		if(pn == NULL)
		  pn = block_first;
	}
	return ERROR;
}

int free(int flag)//主存回收
{
    
    
	LinkNode *p = block_first;
	for (int i = 0; i <= flag; i++)
		if (p != NULL)
			p = p->next;
		else
			return ERROR;

	p->data.state = Free;
    if(p == block_last){
    
    
    	if (p->prior != block_first && p->prior->data.state == Free )//与前面的空闲块相连
	{
    
    
		p->prior->data.size += p->data.size;//空间扩充,合并为一个
		p = p->prior;
		p->next = NULL;
		block_last  = p;
	}
	}
	else{
    
    
	
	if (p->prior != block_first && p->prior->data.state == Free )//与前面的空闲块相连
	{
    
    
		p->prior->data.size += p->data.size;//空间扩充,合并为一个
		p->prior->next = p->next;//去掉原来被合并的p
		p->next->prior = p->prior;
		p = p->prior;
	}
	if (p->next != block_last && p->next->data.state == Free )//与后面的空闲块相连
	{
    
    
		p->data.size += p->next->data.size;//空间扩充,合并为一个
		p->next->next->prior = p;
		p->next = p->next->next;
	}
	if (p->next == block_last && p->next->data.state == Free )//与最后的空闲块相连
	{
    
    
		p->data.size += p->next->data.size;
		p->next = NULL;
	}
}
	return OK;
}

int Combination()     //实现紧凑,合并碎片 
{
    
       
	LinkNode *p = block_first->next;
	int size = 0;
	while(p){
    
                                         
      	if(p->data.state ==Free && p != block_last)    //去除空闲分区 
     	{
    
    
		  size =size + p->data.size ;
		  p->next->prior =p->prior ;
		  p->prior->next = p->next ; 
        }
        else{
    
    
        	p->data.address = p->data.address - size;   //改变地址 
		}
		p = p->next; 
	}
	if(block_last->data.state == Free){
    
         //实现最后合并空闲分区 
	   block_last->data.size += size; 
	}
	else if(size != 0){
    
                         //将所有空闲分区合并放在最后一个分区后面 
		LinkList temp = (LinkList)malloc(sizeof(LinkNode));
		block_last->next =temp;
		temp->prior = block_last;
		temp->next = NULL;
		temp->data.size  = size;
		temp->data.address = block_last->data.address + block_last->data.size ;
		block_last = temp;  
		temp->data.state = Free;
	}
	pn = block_first->next; 
	if(size == 0)   //判断是否有碎片 
	{
    
    
		return ERROR; 
	}
	return OK;
}

void printNode()//显示主存分配情况
{
    
    
	int num = 0;
	printf("                        内存情况                        \n"); 
	cout << "======================================================\n\n";
	LinkNode *p = block_first->next;
	cout << "分区号\t起始地址\t分区大小\t状态\t作业名\n\n";
	while (p)
	{
    
    
		cout << "  " << num++ << "\t";
		cout << "  " << p->data.address << "\t\t";
		cout << " " << p->data.size << "KB\t\t";
		if (p->data.state == Free) {
    
    
			cout << "空闲\n\n";
		}
		else {
    
    
		cout << "已分配\t";
		cout  <<"  "<<p->data.name <<"\n\n";
	    }
	
		
		p = p->next;
	}
	cout << "======================================================\n\n";
}

void Operate(){
    
    
	int choice;  //操作选择标记
	while (1)
	{
    
    
	    menu();
		scanf("%d",&choice);
		if (choice == 1) myMalloc(); // 分配内存
		else if (choice == 2)  // 内存回收
		{
    
    
			int flag;
			cout << "请输入您要释放的分区号:"<<endl;
			cin >> flag;
			free(flag);
		}
		else if (choice == 3) printNode();
		else if(choice == 4)
		{
    
    
			if(Combination() == 0){
    
    
				cout<<"无需合并碎片空间!"<<endl;
			}
			else{
    
    
				cout<<"成功合并碎片!"<<endl;
			}
		}
		else if (choice == 5) break; //退出
		else //输入操作有误
		{
    
    
			cout << "输入有误,请重试!" << endl;
			continue;
		}
	}
}

int main()//主函数
{
    
       
    system("color 5E");
	Init(); //初始化内存状态 
	Operate();
	return 0; 
}

I hope to be helpful.

Guess you like

Origin blog.csdn.net/m0_53788135/article/details/125689199