对象缓冲池

  在游戏开发过程,经常可以碰到一些对象需要不断被创建、销毁,这会导致性能低不说,还会出现内存碎片。以下实现一种可扩展、可重用的对象缓冲池来避免这种情况。

/*
	//可扩展、重复使用的对象缓冲池。
	//功能:等长内存块缓冲式内存池。实现等长内存的快速申请和释放,避免系统级的内存碎片
	//特性:有溢出检查,空间扩充,无重复释放检查,无线程安全
*/

#ifndef __OBJECT_POOL_H__
#define __OBJECT_POOL_H__

#include <list>
#include <iostream>
#include <assert.h>

template <typename T>
class ObjPool_T
{
public:
	// 指定初始数量、增量的数量
	ObjPool_T(int nInitSize = 1, int nIncSize = 1) : m_nIncAllocateSize(nIncSize), m_nAllocatedSize(0)
	{
		if (nInitSize > 0)
		{
			T* pObj = new (std::nothrow) T[nInitSize];
			if (pObj)
			{
				for(int i = 0; i < nInitSize; i++)
					m_listFreeObj.push_back(&pObj[i]);

				m_listObjMass.push_back(pObj);
			}
		}

		if (nIncSize <= 0)
			m_nIncAllocateSize = 1;
	}

	virtual ~ObjPool_T()
	{
		// 检测内存泄漏
		if (m_nAllocatedSize != 0)
			std::cout<<"[Memory leak!!!] doesn't delete "<< m_nAllocatedSize << " object."<<std::endl;

		typename std::list<T*>::iterator it = m_listObjMass.begin();
		for ( ; it != m_listObjMass.end(); it++)
		{
			T* pObj = *it;
			delete [] pObj;
		}

		m_listFreeObj.clear();
		m_listObjMass.clear();
		m_nIncAllocateSize = 0;
	}

	T* Allocate()
	{
		if (m_listFreeObj.empty())
		{
			T* pObj = new (std::nothrow) T[m_nIncAllocateSize];
			if (pObj)
			{
				for (int i = 0; i < m_nIncAllocateSize; i++)
					m_listFreeObj.push_back(&pObj[i]);
				m_listObjMass.push_back(pObj);
			}
			else
				return NULL;
		}

		T* pObj = m_listFreeObj.back();
		m_listFreeObj.pop_back();
		m_nAllocatedSize++;
		return pObj;
	}

	void Free(T* pObj)
	{
		assert(pObj != NULL);
		m_listFreeObj.push_back(pObj);
		m_nAllocatedSize--;
	}
protected:
private:
	std::list<T*>	m_listFreeObj;	//空闲对象
	std::list<T*>	m_listObjMass;	//分配的对象数组
	int m_nAllocatedSize;	// 已经分配的数量
	int m_nIncAllocateSize; // 增量分配的数量
};

#endif //__OBJECT_POOL_H__

  具体使用方法:

#include "ObjectPool.h"

class ObjPoolTest
{
public:
	int m_var;
protected:
private:
};

int main(int argc, char* argv[])
{
	ObjPool_T<ObjPoolTest> ObjPool(5, 2);
	
	ObjPoolTest* pObj = ObjPool.Allocate();
	ObjPool.Free(pObj);

	return 0;
}

  测试代码2:

ObjPool_T<ObjPoolTest> ObjPool(5, 2);
	ObjPoolTest* pObj = ObjPool.Allocate();
	pObj->m_var = 1000;
	ObjPool.Free(pObj);

	ObjPoolTest* pObj2 = ObjPool.Allocate();
	printf("m_var = %d\n", pObj2->m_var);
	ObjPool.Free(pObj2);

  输出:

  问题出现:此问题比较隐蔽,在pObj Free之后内存值并没有清空,pObj2又重用了pObj对应的内存块,此时就出现了pObj2->m_var还是pObj->m_var的值,解决方法请看下回分解。

原文地址:https://www.cnblogs.com/coderyoyo/p/object_pool.html