简明分析C/C++内存分配的解决方案(3)
#include "stdafx.h"
#include "CMemorypool.h"
#include
#include
static const int NEW_ALLOCATED_MEMORY_CONTENT = 0xFF ;
CMemoryPool::CMemoryPool(const std::size_t &sInitialMemoryPoolSize,
const std::size_t &sMemoryChunkSize,
const std::size_t &sMinimalMemorySizeToAllocate,
bool bSetMemoryData)
{
m_ptrFirstChunk = NULL;
m_ptrLastChunk = NULL;
m_ptrCursorChunk = NULL;
m_sTotalMemoryPoolSize = 0;
m_sUsedMemoryPoolSize = 0;
m_sFreeMemoryPoolSize = 0;
m_sMemoryChunkSize = sMemoryChunkSize;
m_uiMemoryChunkCount = 0;
m_uiObjectCount = 0;
m_bSetMemoryData = !bSetMemoryData;
m_sMinimalMemorySizeToAllocate = sMinimalMemorySizeToAllocate;
AllocateMemory(sInitialMemoryPoolSize);
}
CMemoryPool::~CMemoryPool()
{
}
void* CMemoryPool::GetMemory(const std::size_t &sMemorySize)
{
std::size_t sBestMemBlockSize = CalculateBestMemoryBlockSize(sMemorySize);
SMemoryChunk* ptrChunk = NULL;
while(!ptrChunk)
{
ptrChunk = FindChunkSuitableToHoldMemory(sBestMemBlockSize);
//ptrChunk等于NULL表示内存池内存不够用
if(!ptrChunk)
{
sBestMemBlockSize = MaxValue(sBestMemBlockSize, CalculateBestMemoryBlockSize(m_sMinimalMemorySizeToAllocate));
//从OS申请更多的内存
AllocateMemory(sBestMemBlockSize);
}
}
//下面是找到可用的块(Chunk)代码
m_sUsedMemoryPoolSize += sBestMemBlockSize;
m_sFreeMemoryPoolSize -= sBestMemBlockSize;
m_uiObjectCount++;
//标记该块(Chunk)已用
SetMemoryChunkValues(ptrChunk, sBestMemBlockSize);
return ((void *) ptrChunk->Data);
}
void CMemoryPool::FreeMemory(void *ptrMemoryBlock, const std::size_t &sMemoryBlockSize)
{
}
bool CMemoryPool::AllocateMemory(const std::size_t &sMemorySize)
{
//计算可以分多少块(1000 / 128 = 8)
unsigned int uiNeededChunks = CalculateNeededChunks(sMemorySize);
//当内存池的初始大小为1000字节,块(Chunk)大小128字节,分8块还差24字节.怎么办?
//解决方案:多申请24字节
std::size_t sBestMemBlockSize = CalculateBestMemoryBlockSize(sMemorySize);
//向OS申请内存
TByte *ptrNewMemBlock = (TByte*) malloc(sBestMemBlockSize);
//分配一个结构体SmemoryChunk的数组来管理内存块
SMemoryChunk *ptrNewChunks = (SMemoryChunk*) malloc((uiNeededChunks * sizeof(SMemoryChunk)));
m_sTotalMemoryPoolSize += sBestMemBlockSize;
m_sFreeMemoryPoolSize += sBestMemBlockSize;
m_uiMemoryChunkCount += uiNeededChunks;
if(m_bSetMemoryData)
{
memset(((void *) ptrNewMemBlock), NEW_ALLOCATED_MEMORY_CONTENT, sBestMemBlockSize);
}
return LinkChunksToData(ptrNewChunks, uiNeededChunks, ptrNewMemBlock);
}