自己写的内存分配算法

自己写的内存分配算法,即伙伴算法,尝试在网上搜索伙伴算法,发现要么找不到,要么写的看不懂,根据原理自己实现了一个。

// Buddy.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "malloc.h"
#include <list>
#include <set>
using namespace std;

typedef struct stBlockHead
{
	int nSize;
	int nFlag;
	struct stBlockHead *next;
}BlockHead;


BlockHead* g_AllObj[20]={0};
int s_nPos[20]={1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,8192*2,8192*4};
const int s_blockSize = 8192;
int myFree(void *p);
int s_maxPos =0;
char* myAlloc(int nSize);
int myprint();
int GetPos(const int nSize);
char *g_p = NULL;
char *g_pEnd =NULL;
set<void*> g_viewSet;

int _tmain(int argc, _TCHAR* argv[])
{
	char *p = (char *)malloc(s_blockSize);
	g_p =p;
	g_pEnd =g_p + s_blockSize;
	
	s_maxPos = GetPos(s_blockSize);
	BlockHead *pTemp =(BlockHead *)p;
	pTemp->next = NULL;
	pTemp->nFlag =0;
	pTemp->nSize = s_blockSize;
	g_AllObj[s_maxPos] =pTemp;
	

	char *p1= myAlloc(4);
	g_viewSet.insert(p1-8);
	char *p2= myAlloc(100);
	g_viewSet.insert(p2-8);
	char *p3= myAlloc(55);
	g_viewSet.insert(p3-8);

	char *p4= myAlloc(2000);
	g_viewSet.insert(p4-8);
	char *p5= myAlloc(50);
	g_viewSet.insert(p5-8);
	myprint();
	char *p6= myAlloc(50);
	g_viewSet.insert(p6 - 8);
	myprint();

	

	g_viewSet.erase(p1 - 8);
	myFree(p1);
	myprint();
	g_viewSet.erase(p3- 8);
	myFree(p3);
	myprint();
	g_viewSet.erase(p5 - 8);
	myFree(p5);
	myprint();

	g_viewSet.erase(p6 - 8);
	myFree(p6);
	myprint();

	g_viewSet.erase(p2 - 8);
	myFree(p2);
	myprint();


	g_viewSet.erase(p4 - 8);
	myFree(p4);
	myprint();
	
	
	return 0;
}

int GetPos(const int nSize)
{
	for(int i=0;i<20;i++)
	{
		if(s_nPos[i]>=nSize)
			return i;
	}
	return 20;
}

char* myAlloc(int nSize)
{
	if(nSize <0)
		return NULL;
	nSize+=8;
	int nPos = GetPos(nSize);
	if(nPos> s_maxPos)
	{
		printf("memory alloc fail\n");
	}

	if(g_AllObj[nPos] != NULL)
	{
		BlockHead *pTemp =g_AllObj[nPos];
		g_AllObj[nPos]=pTemp->next;
		pTemp->next = NULL;
		return (char *)pTemp+8;
	}
	else
	{
		int i=nPos+1;
		for(;i<20;i++)
		{
			if(g_AllObj[i] !=NULL)
				break;
		}
		
		while(i>nPos)
		{
			BlockHead *pTemp =g_AllObj[i];
			g_AllObj[i] = pTemp->next;
			i--;
			int newSize = pTemp->nSize/2;
			int nFlag = pTemp->nFlag;
			pTemp->nSize = newSize;
			pTemp->nFlag = (nFlag<<1);
			g_AllObj[i]  = pTemp;
			BlockHead *pSecond =(BlockHead *)((char *)pTemp +newSize);
			pSecond->next =NULL;
			pSecond->nFlag = (nFlag<<1)+1;
			pSecond->nSize = newSize;
			pTemp->next = pSecond;
		}

		BlockHead *pTemp = g_AllObj[nPos];
		g_AllObj[nPos] = pTemp->next;
		pTemp->next = NULL;
		return (char *)pTemp+8;

	}

}
int myFree(void *p)
{
	if(p== NULL)
		return -1;
	char *pTemp = (char*)p;
	pTemp -= 8;
	BlockHead *pBlock=(BlockHead *)pTemp;
	int nSize = pBlock->nSize;
	int nFlag = pBlock->nFlag;
	int nPos  = GetPos(nSize);
	if(g_AllObj[nPos] == NULL)
	{
		g_AllObj[nPos] = pBlock;
		printf("test check1\n");
	}
	else
	{
		BlockHead *pPrev = g_AllObj[nPos];
		BlockHead *pNext = pPrev->next;
		if(pBlock < pPrev) //try to merge pBlock and pPrev
		{
			int nFlag1 = pBlock->nFlag;
			int nFlag2 = pPrev->nFlag;

			if(nFlag1 +1 == nFlag2 && (nFlag1>>1)==(nFlag2>>1) )// check if merge pBlock and pPrev
			{
				g_AllObj[nPos] = pNext;
				pBlock->nSize *= 2;
				pBlock->nFlag = nFlag1>>1;
				pBlock->next  = NULL;
				printf("test check2\n");
				myFree((char *)pBlock+8);
			}
			else
			{
				pBlock->next = g_AllObj[nPos];
				g_AllObj[nPos] = pBlock;
			}
		}
		else
		{
			BlockHead *pPrevPrev = NULL;
			while(true)
			{
				if(pNext == NULL)
				{
					break;
				}
				if(pBlock>pPrev && pBlock<pNext)
				{
					break;
				}
				pPrevPrev = pPrev;
				pPrev = pNext;
				pNext = pNext->next;
			}
			if(pNext == NULL)
			{
				
				int nFlag1 = pPrev->nFlag;
				int nFlag2 = pBlock->nFlag;
				if(nFlag1 +1 == nFlag2 &&(nFlag1>>1)==(nFlag2>>1)) // check if merge prev and block
				{
					if(pPrevPrev == NULL)
					{
						g_AllObj[nPos] = NULL;
					}
					else
					{
						pPrevPrev->next = NULL;
					}
					
					pPrev->nSize *= 2;
					pPrev->nFlag = nFlag1>>1;
					pPrev->next = NULL;
					myFree((char *)pPrev+8);
				}
				else
				{
					pPrev->next = pBlock;
					pBlock->next= NULL;
				}
			}
			else
			{
				int nFlag1 = pPrev->nFlag;
				int nFlag2 = pBlock->nFlag; 
				int nFlag3 = pNext->nFlag;
				if(nFlag1 +1 == nFlag2 && (nFlag1>>1)==(nFlag2>>1) )//prev and block
				{
	
						if(pPrevPrev == NULL)
						{
							g_AllObj[nPos] = pNext;
						}
						else
						{
							pPrevPrev->next = pNext;
						}
						pPrev->nSize *=2;
						pPrev->nFlag = nFlag2>>1;
						pPrev->next = NULL;
						myFree((char *)pPrev + 8);
				}
				else if(nFlag2 +1 == nFlag3 &&(nFlag2>>1) ==(nFlag3>>1))//pBlock and pNext
				{
					pPrev->next = pNext->next;
					pBlock->next = NULL;
					pBlock->nSize *= 2;
					pBlock->nFlag = nFlag2>>1;
					myFree((char *)pBlock+8);
				}
				else
				{
					pPrev->next  = pBlock;
					pBlock->next = pNext;
				}
			}
			
		}

	}
	return 0;
}



int myprint()
{
	int i=0;
	char *pTravel =g_p;
	while(pTravel !=g_pEnd)
	{
		BlockHead *pHead =(BlockHead *)pTravel;
		if(g_viewSet.find(pTravel) != g_viewSet.end())
		{
			printf("pos %d   使用:address :0x%x,size is %d,flag is :%d\n",i,pHead,pHead->nSize,pHead->nFlag);
		}
		else
		{
			printf("pos %d 未使用:address :0x%x,size is %d,flag is :%d\n",i,pHead,pHead->nSize,pHead->nFlag);
		}
		pTravel+=pHead->nSize;
		i++;
	}
	printf("----------------------------------------\n");
	return 0;
}


以下是一个简单的物理内存分配算法的C语言实现,使用了首次适应算法: ```c #include <stdio.h> #define MEM_SIZE 1000 //物理内存大小 #define FREE 0 //空闲内存标志 #define OCCUPIED 1 //占用内存标志 int memory[MEM_SIZE]; //物理内存数组 int process_num = 0; //进程数量 //初始化物理内存数组 void init_memory() { for (int i = 0; i < MEM_SIZE; i++) { memory[i] = FREE; } } //分配内存 int allocate_memory(int psize) { int start = -1; //起始位置 for (int i = 0; i < MEM_SIZE; i++) { if (memory[i] == FREE) { //找到空闲内存 int j = i; while (j < MEM_SIZE && memory[j] == FREE && j-i+1 < psize) { //查找连续空闲内存 j++; } if (j-i+1 == psize) { //找到足够大的连续空闲内存 start = i; break; } } } if (start == -1) { //未找到足够大的连续空闲内存 return -1; } for (int i = start; i < start+psize; i++) { //将内存标记为占用 memory[i] = OCCUPIED; } process_num++; //进程数量加1 return start; } //释放内存 void free_memory(int start, int psize) { for (int i = start; i < start+psize; i++) { //将内存标记为空闲 memory[i] = FREE; } process_num--; //进程数量减1 } int main() { init_memory(); //初始化物理内存 int pid1 = allocate_memory(200); //分配200字节内存 if (pid1 != -1) { printf("Process 1 allocated memory from %d to %d.\n", pid1, pid1+199); printf("Memory usage: %d / %d\n", process_num, MEM_SIZE); } else { printf("Memory allocation failed.\n"); } int pid2 = allocate_memory(300); //分配300字节内存 if (pid2 != -1) { printf("Process 2 allocated memory from %d to %d.\n", pid2, pid2+299); printf("Memory usage: %d / %d\n", process_num, MEM_SIZE); } else { printf("Memory allocation failed.\n"); } free_memory(pid1, 200); //释放200字节内存 printf("Process 1 freed memory from %d to %d.\n", pid1, pid1+199); printf("Memory usage: %d / %d\n", process_num, MEM_SIZE); int pid3 = allocate_memory(500); //分配500字节内存 if (pid3 != -1) { printf("Process 3 allocated memory from %d to %d.\n", pid3, pid3+499); printf("Memory usage: %d / %d\n", process_num, MEM_SIZE); } else { printf("Memory allocation failed.\n"); } return 0; } ``` 注释: - `#define MEM_SIZE 1000`:定义物理内存大小为1000字节。 - `#define FREE 0`:定义空闲内存标志为0。 - `#define OCCUPIED 1`:定义占用内存标志为1。 - `int memory[MEM_SIZE]`:定义物理内存数组。 - `int process_num = 0`:定义进程数量,初始值为0。 - `void init_memory()`:初始化物理内存数组,将所有元素赋值为FREE。 - `int allocate_memory(int psize)`:分配内存,psize为请求内存大小,返回分配的起始位置,若分配失败返回-1。 - `void free_memory(int start, int psize)`:释放内存,start为释放的起始位置,psize为请求内存大小。 - `int main()`:主函数。 - `init_memory()`:初始化物理内存。 - `int pid1 = allocate_memory(200)`:分配200字节内存,返回分配的起始位置,若分配失败返回-1。 - `if (pid1 != -1)`:如果分配成功。 - `printf("Process 1 allocated memory from %d to %d.\n", pid1, pid1+199)`:输出分配的起始位置和结束位置。 - `printf("Memory usage: %d / %d\n", process_num, MEM_SIZE)`:输出内存使用情况。 - `int pid2 = allocate_memory(300)`:分配300字节内存。 - `if (pid2 != -1)`:如果分配成功。 - `printf("Process 2 allocated memory from %d to %d.\n", pid2, pid2+299)`:输出分配的起始位置和结束位置。 - `printf("Memory usage: %d / %d\n", process_num, MEM_SIZE)`:输出内存使用情况。 - `free_memory(pid1, 200)`:释放200字节内存。 - `printf("Process 1 freed memory from %d to %d.\n", pid1, pid1+199)`:输出释放的起始位置和结束位置。 - `printf("Memory usage: %d / %d\n", process_num, MEM_SIZE)`:输出内存使用情况。 - `int pid3 = allocate_memory(500)`:分配500字节内存。 - `if (pid3 != -1)`:如果分配成功。 - `printf("Process 3 allocated memory from %d to %d.\n", pid3, pid3+499)`:输出分配的起始位置和结束位置。 - `printf("Memory usage: %d / %d\n", process_num, MEM_SIZE)`:输出内存使用情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值