使用通用对象分配器来实现内存管理分配器,并可在程序结束时自动回收。
模板分配器基类
/*
通用对象分配器,可一次分配多个
*/
template <typename T>
class CBaseObjAllocator
{
public:
//内存块描述结构,用于查询内存块信息
struct DataBlockDesc
{
const char* lpBaseAddress;//内存块指针地址
size_t dwBlockSize; //内存块大小
};
private:
//内存块链表节点
struct DataBlock
{
T* pFreePtr;//指向空闲的对象
T* pEndPtr;//指向对象内存块的结束
DataBlock* pPrev;
}*m_pDataBlock;
public:
enum {
AllocObjectCountOneTime = 1024;//每次申请内存大小
};
T* allocObject()
{
return allocObjects(1);
}
//申请属性指针
T* allocObjects(const INT_PTR nCount = 1)
{
T* result;
DataBlock *pBlock = m_pDataBlock;
//尝试从当前内存块中申请nCount的对象,如果内存块中没有足够的对象,则向之前的内存块中查找是否具有足够的空闲对象
if ( !pBlock || pBlock->pEndPtr - pBlock->pFreePtr < nCount )
{
//向之前的内存块中查找是否具有足够的空闲对象
while (pBlock && (pBlock = pBlock->pPrev))
{
if ( pBlock->pEndPtr - pBlock->pFreePtr >= nCount )
break;
}
//如果所有内存块中都没有足够的对象则申请新内存块
if ( pBlock == NULL )
{
INT_PTR nAllocCount = __max(nCount, AllocObjectCountOneTime);//最小1024字节
pBlock = (DataBlock*)malloc(sizeof(DataBlock) + sizeof(T) * nAllocCount);
memset(pBlock, 0, sizeof(DataBlock) + sizeof(T) * nAllocCount);
pBlock->pFreePtr = (T*)(pBlock + 1);//跳过块头
pBlock->pEndPtr = pBlock->pFreePtr + nAllocCount;//块内存结尾
pBlock->pPrev = m_pDataBlock;//插入新块到链表的头部
m_pDataBlock = pBlock;
}
}
//返回对象指针
result = pBlock->pFreePtr;//返回满足需求的内存地址
pBlock->pFreePtr += nCount;
return result;
}
//获取内存块数量
inline INT_PTR blockCount() const
{
INT_PTR result = 0;
DataBlock *pBlock = m_pDataBlock;
while (pBlock)
{
result++;
pBlock = pBlock->pPrev;
}
return result;
}
CBaseObjAllocator()
{
m_pDataBlock = NULL;
}
~CBaseObjAllocator()//对象分配器的内存是在析构时回收的
{
DataBlock *pBlock, *pPrev;//释放内存块链表
pBlock = m_pDataBlock;
while (pBlock)
{
pPrev = pBlock->pPrev;
free(pBlock);
pBlock = pPrev;
}
m_pDataBlock = NULL;
}
};
加载配置使用的内存分配器。因为内存分配器的内存是在析构时回收的,所以不需要手动回收内存。
class CConfigAllocator : public CBaseObjAllocator<char>
{
public:
typedef CBaseObjAllocator<char> super;//内存分配器的单位是1字节
public:
template<typename T>
inline T* Alloc(size_t count)//分配
{
size_t sz = sizeof(T) * count;
return (T*)super::allocObjects(sz);
}
inline char* AllocStr(const std::string& str)
{
size_t len = str.length();
size_t sz = (len + 1) * sizeof(char);
char *result = (char*)super::allocObjects(sz);
memcpy(result, str.c_str(), len * sizeof(char));//拷贝string的内容到分配的内存里
result[len] = 0;//结束符
return result;
}
};