C++中一个高效的内存池实现 (一)

2014-11-24 12:06:15 · 作者: · 浏览: 2

在高效C++编程中看到一个不错的内存池实现方案,这里共享下,大家看看有什么不足。
代码很简单,如下:
template
class CMemoryPool
{
public:
enum { EXPANSION_SIZE = 32};

CMemoryPool(unsigned int nItemCount = EXPANSION_SIZE)
{
ExpandFreeList(nItemCount);
}

~CMemoryPool()
{
//free all memory in the list
CMemoryPool* pNext = NULL;
for(pNext = m_pFreeList; pNext != NULL; pNext = m_pFreeList)
{
m_pFreeList = m_pFreeList->m_pFreeList;
delete [](char*)pNext;
}
}

void* Alloc(unsigned int /*size*/)
{
if(m_pFreeList == NULL)
{
ExpandFreeList();
}

//get free memory from head
CMemoryPool* pHead = m_pFreeList;
m_pFreeList = m_pFreeList->m_pFreeList;
return pHead;
}

void Free(void* p)
{
//push the free memory back to list
CMemoryPool* pHead = static_cast*>(p);
pHead->m_pFreeList = m_pFreeList;
m_pFreeList = pHead;
}

protected:
//allocate memory and push to the list
void ExpandFreeList(unsigned nItemCount = EXPANSION_SIZE)
{
unsigned int nSize = sizeof(T) > sizeof(CMemoryPool*) sizeof(T) : sizeof(CMemoryPool*);
CMemoryPool* pLastItem = static_cast*>(static_cast(new char[nSize]));
m_pFreeList = pLastItem;
for(int i=0; i {
pLastItem->m_pFreeList = static_cast*>(static_cast(new char[nSize]));
pLastItem = pLastItem->m_pFreeList;
}

pLastItem->m_pFreeList = NULL;
}

private:
CMemoryPool* m_pFreeList;
};

它的实现思想就是每次从List的头上取内存, 如果取不到则重新分配一定数量; 用完后把内存放回List头部,这样的话效率很高,因为每次List上可以取到的话,肯定是空闲的内存。

当然上面的代码只是针对单线程的,要支持多线程的话也很简单,外面加一层就可以了,
代码如下:
class CCriticalSection
{
public:
CCriticalSection()
{
InitializeCriticalSection(&m_cs);
}

~CCriticalSection()
{
DeleteCriticalSection(&m_cs);
}

void Lock()
{
EnterCriticalSection(&m_cs);
}

void Unlock()
{
LeaveCriticalSection(&m_cs);
}

protected:
CRITICAL_SECTION m_cs;
};

template
class CMTMemoryPool
{
public:
void* Alloc(unsigned int size)
{
void* p = NULL;
m_lock.Lock();
p = m_pool.Alloc(size);
m_lock.Unlock();

return p;
}

void Free(void* p)
{
m_lock.Lock();
m_pool.Free(p);
m_lock.Unlock();
}

private:
POOLTYPE m_pool;
LOCKTYPE m_lock;
};

这是我的测试代码:
#include
#include

using namespace std;

#include "MemoryPool.h"
#include "MTMemoryPool.h"

class CTest
{
public:
int m_n;
int m_n1;

void* operator new(size_t size)
{
void* p = s_pool->Alloc(size);
return p;
}

void operator delete(void* p, size_t size)
{
s_pool->Free(p);
}

static void NewPool()
{
//s_pool = new CMemoryPool;
s_pool = new CMTMemoryPool, CCriticalSection>;
}

static void DeletePool()
{
delete s_pool;
s_pool = NULL;
}

//static CMemoryPool* s_pool;
static CMTMemoryPool, CCriticalSection>* s_po