Game Development Reference
In-Depth Information
from this block. In this example, the fragmentation is redundant because we have not implemented
any way of tracking our free blocks of memory. One option would be to use a list to store all of
the free blocks rather than storing them in the memory allocation headers themselves. Writing a
full-featured memory allocator is a complicated task that could fill an entire book.
Note
You can see that we have a valid case for using
reinterpret_cast
in our
new
and
delete
operators. There aren't many valid cases for this type of cast. In this case we want to represent the same
memory address using a different type and therefore the
reinterpret_cast
is the correct option.
Listing 22-9 contains the last memory function for this section and it is used to print out the contents
of all active
MemoryAllocationHeader
objects in our heap.
Listing 22-9. The
PrintAllocations
Function
void PrintAllocations()
{
MemoryAllocationHeader* pHeader =
reinterpret_cast<MemoryAllocationHeader*>(pMemoryHeap);
while (pHeader != nullptr)
{
std::cout << pHeader << std::endl;
std::cout << pHeader->pStart << std::endl;
std::cout << pHeader->pNextFree << std::endl;
std::cout << pHeader->size << std::endl;
pHeader = reinterpret_cast<MemoryAllocationHeader*>(pHeader->pNextFree);
std::cout << std::endl << std::endl;
}
}
This function loops over all of the valid
MemoryAllocationHeader
pointers in our head and prints
their
pStart
,
pNextFree
, and
size
variables. Listing 22-10 shows an example
main
function that uses
these functions.
Listing 22-10. Using the Memory Heap
int _tmain(int argc, _TCHAR* argv[])
{
memset(pMemoryHeap, 0, SIZE_OF_MEMORY_HEADER);
PrintAllocations();
Simple* pSimple1 = new Simple();