|
贴个自写的内存管理类。
#include
#include
struct MemInfo
{
unsigned int iMemSize;
bool bUse;
void* pMem;//标识内存的起始地址,在m_pMem中
};
typedef CArray CMemArray;
//问题要不要考虑页面边界及字节对齐的问题???
class CMemoryManager
{
public:
bool HasInit();
CMemoryManager();
virtual ~CMemoryManager();
void* MemNew(size_t size);
void MemDelete(void* p);
bool Init();//最开始来标识是否成功//整个实例只能运行一次
CMemArray& GetArray();
private:
void DoMemCombinate(int iIndex,MemInfo* pInfo);
private:
void* m_pMem;
CMemArray m_oMemArray;
CCriticalSection m_cs;//对此对象的lock不关乎成员,等待此对象的信号
HANDLE m_hHeap;
};
CPP:
CMemoryManager::CMemoryManager()
{
m_pMem = NULL;
m_hHeap = NULL;
m_oMemArray.RemoveAll();
}
CMemoryManager::~CMemoryManager()
{
for(int i = 0; i < m_oMemArray.GetSize(); i++)
{
MemInfo* pInfo = m_oMemArray.GetAt(i);
delete pInfo;
//dont delete pInfo->pMem;
}
m_oMemArray.RemoveAll();
//256kb
if(NULL != m_pMem)
{
HeapFree(m_hHeap,0x40000,m_pMem);
HeapDestroy(m_hHeap);
}
}
//分配堆,在堆中分出自己要用的内存
bool CMemoryManager::Init()
{
m_hHeap = HeapCreate(HEAP_NO_SERIALIZE,0x40500,0x50000);
if(NULL == m_hHeap)
{
return false;
}
m_cs.Lock();
m_pMem = HeapAlloc(m_hHeap,HEAP_ZERO_MEMORY,0x40000);
if(NULL == m_pMem)
{
m_cs.Unlock();
return false;
}
//内存小,delete影响小
MemInfo* pInfo = new MemInfo;
if(NULL == pInfo)
{
m_cs.Unlock();
return false;
}
pInfo->pMem = m_pMem;
pInfo->iMemSize = 0x40000;
pInfo->bUse = false;
m_oMemArray.Add(pInfo);
m_cs.Unlock();
return true;
}
//new一块内存,实际分配要不要更大点?
//思想是找最小适合空闲块来分配
void* CMemoryManager::MemNew(size_t size)
{
MemInfo* pTemp = NULL;//标识空闲块
unsigned int uiSize = 0;
for(int i = 0 ; i < m_oMemArray.GetSize(); i++)
{
MemInfo* pInfo = m_oMemArray.GetAt(i);
if(NULL != pInfo)
{
//找最小块
if(pInfo->iMemSize >= size && !pInfo->bUse)
{
if(uiSize <= 0)
{
uiSize = pInfo->iMemSize;
pTemp = pInfo;
}
else
{
if(pInfo->iMemSize < uiSize)
{
uiSize = pInfo->iMemSize;
pTemp = pInfo;
}
}
}
}
}
if(NULL == pTemp)
{
return NULL;
}
m_cs.Lock();
if(pTemp->iMemSize == size)
{
pTemp->bUse = true;
m_cs.Unlock();
return pTemp->pMem;
}
else
{
MemInfo* pNewInfo = new MemInfo;
pNewInfo->iMemSize = size;
pNewInfo->bUse = true;
pNewInfo->pMem = pTemp->pMem;
pTemp->iMemSize -= size;
pTemp->pMem = (void*)((DWORD)pTemp->pMem + size);
m_oMemArray.Add(pNewInfo);
m_cs.Unlock();
return pNewInfo->pMem;
}
m_cs.Unlock();
return NULL;
}
//回收空闲块,当空闲块的前一块或后一块也为空闲则合并
void CMemoryManager::MemDelete(void* p)
{
if(NULL == p)
{
return;
}
for(int i = 0; i < m_oMemArray.GetSize(); i++)
{
MemInfo* pInfo = m_oMemArray.GetAt(i);
if(NULL != pInfo)
{
if(pInfo->pMem == p)
{
m_cs.Lock();
memset(pInfo->pMem,0,pInfo->iMemSize);
pInfo->bUse = false;
DoMemCombinate(i,pInfo);
m_cs.Unlock();
return;
}
}
}
}
void CMemoryManager::DoMemCombinate(int iIndex,MemInfo* pInfo)
{
int iPre = -1,iNext = -1;
if(iIndex > 0)
{
iPre = iIndex - 1;
}
if(iIndex < m_oMemArray.GetSize() - 1)
{
iNext = iIndex + 1;
}
bool bRemove = false;
if( -1 != iPre)
{
MemInfo* pMemPre = NULL;
pMemPre = m_oMemArray.GetAt(iPre);
if(!pMemPre->bUse)
{
pInfo->iMemSize += pMemPre->iMemSize;
pInfo->pMem = pMemPre->pMem;
bRemove = true;
//须最后移去
delete pInfo;
}
}
if( -1 != iNext)
{
MemInfo* pMemNext = NULL;
pMemNext = m_oMemArray.GetAt(iNext);
if(!pMemNext->bUse)
{
pInfo->iMemSize += pMemNext->iMemSize;
delete pInfo;
m_oMemArray.RemoveAt(iNext);
}
}
if(bRemove)
{
m_oMemArray.RemoveAt(iPre);
}
}
bool CMemoryManager::HasInit()
{
return m_pMem?true:false;
}
CMemArray& CMemoryManager::GetArray()
{
return m_oMemArray;
} |
|