内存池
下午花时间写了一个内存管理的类,每次分配一个固定大小的对象,基本的处理原则就是下面的4点:
1. 动态增长,尽量使用连续内存
2. 分配内存地址的不变性
3. 快速分配和回收
4. 便于管理
也贴出来现现丑,代码如下:
#ifndef __C_POOL_MANAGER_H_
#define __C_POOL_MANAGER_H_
//
// a generic object pool manager
// by sparkling
//
typedef unsigned int u32;
// #define MEM_ENTRY(ptr, type, member) ((type *)((s8 *)(ptr)-(u32)(&((type *)0)->member)))
template <class T>
class CPoolManager
{
public:
CPoolManager():m_vecItemList(0), m_freeItemList(0), m_uiCapacity(0), m_uiCurSize(0)
{AllocateOnce();}
~CPoolManager() {DestroyAll();}
enum{ITEM_ARRAY_SIZE=256};
public:
T *Get(); // get a free item
void ReleaseToPool(const T *t); // return t to free list
u32 GetCapacity() const {return m_uiCapacity;}
u32 GetCurSize() const {return m_uiCurSize;}
u32 GetFreeCount() const {return (m_uiCapacity - m_uiCurSize);}
void AllocateOnce();
void DestroyAll(); // free all the memory
protected:
struct ITEM{
T _t;
ITEM *_next; // next free item
};
struct ITEM_ARRAY{
ITEM _vecItems[ITEM_ARRAY_SIZE];
ITEM_ARRAY *_next; // next item array list
};
void pushHead(ITEM *newItem)
{newItem->_next = m_freeItemList; m_freeItemList = newItem;}
protected:
ITEM_ARRAY *m_vecItemList;
ITEM *m_freeItemList;
u32 m_uiCapacity;
u32 m_uiCurSize;
};
template <class T>
T *CPoolManager<T>::Get()
{
if(m_freeItemList == 0) AllocateOnce(); // need allocate new buffer
if(m_freeItemList){
m_uiCurSize++;
ITEM *tmp = m_freeItemList;
m_freeItemList = m_freeItemList->_next;
return &(tmp->_t);
}
return 0;
}
template <class T>
void CPoolManager<T>::ReleaseToPool(const T *t)
{
if(t){
ITEM *p = (ITEM*)t;// MEM_ENTRY(t, ITEM, _t);
pushHead(p);
m_uiCurSize--;
}
}
template <class T>
void CPoolManager<T>::AllocateOnce()
{
// allocate an item array, and insert at head
ITEM_ARRAY *vecNewItems = new ITEM_ARRAY;
vecNewItems->_next = m_vecItemList;
m_vecItemList = vecNewItems;
for(int i = 0; i < ITEM_ARRAY_SIZE; ++i){
pushHead(&(vecNewItems->_vecItems[i]));
}
m_uiCapacity += ITEM_ARRAY_SIZE;
}
template <class T>
void CPoolManager<T>::DestroyAll()
{
ITEM_ARRAY *tmp = m_vecItemList;
while(tmp){
m_vecItemList = tmp->_next;
delete tmp;
tmp = m_vecItemList;
}
m_uiCapacity = m_uiCurSize = 0;
m_vecItemList = 0;
m_freeItemList = 0;
}
#endif // __C_POOL_MANAGER_H_