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