自己写的内存分配算法,即伙伴算法,尝试在网上搜索伙伴算法,发现要么找不到,要么写的看不懂,根据原理自己实现了一个。
// 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;
}