213
// Store the adjustment in the four bytes immediately
// preceding the adjusted address that we’re
// returning.
U32* pAdjustment = (U32*)(alignedAddress – 4);
*pAdjustment = adjustment;
return (void*)alignedAddress;
}
And here’s how the corresponding freeAligned() function would be imple-
mented.
voidfreeAligned(void* p)
{
U32 alignedAddress = (U32)p;
U8* pAdjustment = (U8*)(alignedAddress – 4);
U32 adjustment = (U32)*pAdjustment;
U32 rawAddress = alignedAddress – adjustment;
freeUnaligned((void*)rawAddress);
}
5.2.1.4. Single-Frame and Double-Buffered Memory Allocators
Virtually all game engines allocate at least some temporary data during the
game loop. This data is either discarded at the end of each iteration of the loop
or used on the next frame and then discarded. This allocation patt ern is so
common that many engines support single- and double-buff ered allocators.
Single-Frame Allocators
A single-frame allocator is implemented by reserving a block of memory and
managing it with a simple stack allocator as described above. At the beginning
of each frame, the stack’s “top” pointer is cleared to the bott om of the memory
block. Allocations made during the frame grow toward the top of the block.
Rinse and repeat.
StackAllocatorg_singleFrameAllocator;
// Main Game Loop
while (true)
{
// Clear the single-frame allocator’s buffer every
// frame.
g_singleFrameAllocator. clear();
5.2. Memory Management