在游戏开发过程,经常可以碰到一些对象需要不断被创建、销毁,这会导致性能低不说,还会出现内存碎片。以下实现一种可扩展、可重用的对象缓冲池来避免这种情况。
/* //可扩展、重复使用的对象缓冲池。 //功能:等长内存块缓冲式内存池。实现等长内存的快速申请和释放,避免系统级的内存碎片 //特性:有溢出检查,空间扩充,无重复释放检查,无线程安全 */ #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的值,解决方法请看下回分解。