• 对象缓冲池


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

    /*
    	//可扩展、重复使用的对象缓冲池。
    	//功能:等长内存块缓冲式内存池。实现等长内存的快速申请和释放,避免系统级的内存碎片
    	//特性:有溢出检查,空间扩充,无重复释放检查,无线程安全
    */
    
    #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的值,解决方法请看下回分解。

  • 相关阅读:
    反射
    IDEA配置数据库
    配置idea的maven镜像为aliyun
    蓝桥---芯片测试(思维)
    汉诺塔(思维、DP思想)
    立方数(质因子、优化)
    碎碎念(DP)
    牛牛战队的比赛地(三分)
    子段乘积(尺取、逆元)
    子段异或(位运算)
  • 原文地址:https://www.cnblogs.com/coderyoyo/p/object_pool.html
Copyright © 2020-2023  润新知