内存池实现

头文件 MemoryPool.h:

#ifndef _MEMORY_POOL_H_
#define _MEMORY_POOL_H_

#ifndef NULL
#define NULL 0
#endif

typedef unsigned char  Uint8;
typedef unsigned short Uint16;
typedef unsigned long  Uint32;

struct MemoryBlock
{
	Uint32			m_nSize;	//数据缓冲总字节数
	Uint16			m_nFree;	//空闲元素的个数
	Uint16			m_nFirst;	//第一个空闲元素的索引
	MemoryBlock*	m_pNext;	//下一个数据分配单元的地址
	Uint8			m_aData[1];	//元素数组的第一个元素

	static void* operator new(size_t size, Uint16 nUnitCount, Uint16 nUnitSize)
	{
		return ::operator new(sizeof(MemoryBlock) + nUnitCount * nUnitSize);
	}

	static void operator delete(void* p, size_t)
	{
		::operator delete(p);
	}

	MemoryBlock(Uint16 nUnitCount = 1, Uint16 nUnitSize = 0);
	~MemoryBlock() {}
};

class MemoryPool
{
private:
	MemoryBlock*	m_pBlock;
	Uint16			m_nUnitSize;	//元素大小
	Uint16			m_nInitSize;	//内存池初始元素的个数
	Uint16			m_nGrowSize;	//内存池空间不够后每次元素增长的个数

public:
	MemoryPool(Uint16 nUnitSize, Uint16 nInitSize = 1024, Uint16 nGrowSize = 256);
	~MemoryPool();

	void* Alloc();
	void  Free(void* p);
};

#endif //~_MEMORY_POOL_H_


实现文件 MemoryPool.cpp

#include "MemoryPool.h"

#define MEMORYPOOL_ALIGNMENT 4

/*-------------- MemoryBlock --------------*/

MemoryBlock::MemoryBlock(Uint16 nUnitCount, Uint16 nUnitSize) :
	m_nSize(nUnitCount * nUnitSize),
	m_nFree(nUnitCount - 1),
	m_nFirst(1),
	m_pNext(NULL)
{
	Uint8* pData = m_aData;

	for(Uint16 i = 1; i < nUnitCount; i++)
	{
		*reinterpret_cast<Uint16*>(pData) = i;
		pData += nUnitSize;
	}
}

/*-------------- MemoryPool --------------*/

MemoryPool::MemoryPool(Uint16 nUnitSize, Uint16 nInitSize/* = 1024*/, Uint16 nGrowSize/* = 256*/) :
	m_pBlock(NULL),
	m_nInitSize(nInitSize),
	m_nGrowSize(nGrowSize)
{
	if(nUnitSize > 4)
		m_nUnitSize = (nUnitSize + (MEMORYPOOL_ALIGNMENT-1)) & ~(MEMORYPOOL_ALIGNMENT-1);
	else if(nUnitSize <= 2)
		m_nUnitSize = 2;
	else
		m_nUnitSize = 4;
}

void* MemoryPool::Alloc()
{
	if(m_pBlock == NULL)
	{
		//......
		m_pBlock = new(m_nInitSize, m_nUnitSize) MemoryBlock(m_nInitSize, m_nUnitSize);
		if(!m_pBlock)
			return NULL;

		return (void*)m_pBlock->m_aData;
	}

	MemoryBlock* pMyBlock = m_pBlock;

	while(pMyBlock && !pMyBlock->m_nFree)
		pMyBlock = pMyBlock->m_pNext;

	if(pMyBlock)
	{
		Uint8* pFree = pMyBlock->m_aData + (pMyBlock->m_nFirst * m_nUnitSize);
		pMyBlock->m_nFirst = *(Uint16*)pFree;

		pMyBlock->m_nFree--;

		return (void*)pFree;
	}
	else
	{
		if(!m_nGrowSize)
			return NULL;

		pMyBlock = new(m_nGrowSize, m_nUnitSize) MemoryBlock(m_nGrowSize, m_nUnitSize);
		if(!pMyBlock)
			return NULL;

		pMyBlock->m_pNext = m_pBlock;
		m_pBlock = pMyBlock;

		return (void*)(pMyBlock->m_aData);
	}
}

void MemoryPool::Free(void* pFree)
{
	//.....

	MemoryBlock* pMyBlock	= m_pBlock;
	MemoryBlock* pPrevBlock = m_pBlock;

	while((pMyBlock->m_aData > pFree) || (pFree >= (pMyBlock->m_aData + pMyBlock->m_nSize)))
	{
		//.....
		pPrevBlock	= pMyBlock;
		pMyBlock	= pMyBlock->m_pNext;
		if(!pMyBlock)
			return ;
	}

	pMyBlock->m_nFree++;
	*((Uint16*)pFree)	= pMyBlock->m_nFirst;
	pMyBlock->m_nFirst	= (Uint16)(((Uint32)pFree - (Uint32)pMyBlock->m_aData) / m_nUnitSize);	//计算并设置当前释放的是第几个内存单元块的位置

	if((Uint32)pMyBlock->m_nFree*(Uint32)m_nUnitSize == pMyBlock->m_nSize)
	{
		//所有内存单元块全部被释放 .....
		pPrevBlock->m_pNext = pMyBlock->m_pNext;
		delete pMyBlock;
	}
}

MemoryPool::~MemoryPool()
{
	MemoryBlock* pMyBlock = m_pBlock;
	while(pMyBlock)
	{
		//.....
		MemoryBlock* pDelBlock = pMyBlock;
		pMyBlock = pMyBlock->m_pNext;
		delete pDelBlock;
	}
}

测试代码:

#include <stdio.h>
#include <tchar.h>
#include "MemoryPool.h"

#define _CRTDBG_MAP_ALLOC 1
#include <crtdbg.h>
#include <Windows.h>

const int MALLOC_COUNT = 500 * 10000;

int _tmain(int argc, _TCHAR* argv[])
{
	MemoryPool* pPool = new MemoryPool(5, 20000, 20000);

	Uint32 start = GetTickCount();

	for(int i = 0; i < MALLOC_COUNT; i++)
	{
		void* pp = pPool->Alloc();
	}

	Uint32 tick0 = GetTickCount() - start;
	
	start = GetTickCount();

	for(int i = 0; i < MALLOC_COUNT; i++)
	{
		void* pp = malloc(5);
	}

	Uint32 tick1 = GetTickCount() - start;
	
	printf("Mempool Alloc used time: %d\n", tick0);
	printf("System malloc used time: %d\n", tick1);

	void* p1 = pPool->Alloc();
	void* p2 = pPool->Alloc();
	void* p3 = pPool->Alloc();
	void* p4 = pPool->Alloc();
	void* p5 = pPool->Alloc();

	pPool->Free(0);
	pPool->Free(p1);
	pPool->Free(p2);
	pPool->Free(p5);
	pPool->Free(p3);

	p1 = pPool->Alloc();

	delete pPool;

	//_CrtDumpMemoryLeaks();

	return 0;
}


测试结果:


测试环境: Win7 + VS2008 + Release + 2GRAM + Intel(R) Core(TM)2 Quad CPU Q8300 @ 2.50GHz

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值