Game Development Reference
In-Depth Information
m_pHead = GetNext(m_pHead);
return (pRet + CHUNK_HEADER_SIZE); // make sure we return a pointer to
// the data section only
}
void MemoryPool::Free(void* pMem)
{
// Calling Free() on a NULL pointer is perfectly valid C++ so
// we have to check for it.
if (pMem != NULL)
{
// The pointer we get back is just to the data section of
// the chunk. This gets us the full chunk.
unsigned char* pBlock =
((unsigned char*)pMem) - CHUNK_HEADER_SIZE;
// push the chunk to the front of the list
SetNext(pBlock, m_pHead);
m_pHead = pBlock;
}
}
The first thing the
Alloc()
function checks is whether or not the block has been
fully allocated. If it has, it has to allocate a new block. You can disallow this by set-
ting
m_toAllowResize
to
false
. This is handy for games that have a limited
memory budget, like console or mobile games. After that, it returns the front of the
list:
return (pRet + CHUNK_HEADER_SIZE);
Notice how it adds the
CHUNK_HEADER_SIZE
? This is necessary because you only
want to return the actual data section and not include the header section.
The
Free()
function is pretty much the reverse. If the chunk is valid, the function
subtracts
CHUNK_HEADER_SIZE
to get the full chunk, including the header. Then it
sets the header to point to the current front of the list and assigns the
m_pHead
pointer to itself. This pushes the freed chunk to the front of the list.
In practice, the best way to use this memory pool is to figure out which objects you
ll
be constructing and destroying extremely often and make them use a memory pool.
The best way to do this is to override the
new
and
delete
operators for that class so
that they call into the memory pool for allocation and deallocation. This keeps it nice
and contained within the class so that the calling code doesn
'
'
t have to know anything
—
about whether the class is pooled or not
it just calls
new
and
delete
as normal.