自己寫的內存分配算法

自己寫的內存分配算法,即夥伴算法,嘗試在網上搜索夥伴算法,發現要麼找不到,要麼寫的看不懂,根據原理自己實現了一個。

// 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;
}


發佈了105 篇原創文章 · 獲贊 35 · 訪問量 23萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章