I suggest using the approach of a LIFO (stack).
Psuedo-code datastructure:
Code:
structure MemoryPool
ptr MemoryBlock pFreeListHead;
integer nBlockSize
integer nTotalBlocksCount
integer nFreeBlocksCount
long integer nAllocations
long integer nDeletions
ptr void pMemoryStart
ptr void pMemoryEnd
structure MemoryBlock
hex Guardband
integer Size
ptr MemoryBlock next
ptr MemoryPool pPoolOwner
8-bit State { ALLOC, FREE, FROM_HEAP }
hex Guardband
And the psuedo-code for using:
Code:
initialize_pool(ptr structure MemoryPool pool, ... /* configuration parameters (size, count) */)
clear pool
internally allocate enough memory to hold (count number of memory blocks + count * size)
set pool pMemoryStart and pMemoryEnd
starting at the last byte of memory and for each count:
advance size bytes earlier, and size of MemoryBlock bytes earlier
treat the current position as a MemoryBlock and initialize
set the state to FREE
set MemoryBlock next to pool pFreeListHead
set pool pFreeListHead to current MemoryBlock
ptr void allocate_buffer(ptr structure MemoryPool pool)
ptr MemoryBlock buffer_ equals pool pFreeListHead
if(buffer_)
set buffer_ state to ALLOC
set pool pFreeListHead to buffer_ next
return ptr to the bytes just after the buffer_ header
/* else it is up to you to handle the case of no more buffers */
delete_buffer(ptr structure MemoryPool pool, ptr void Buffer)
/* you merely have to ensure that the Buffer header is correct, and pFreeListHead of pool is updated correctly */
It's up to you to actually write the code, and also to think about synchronization issues (and how to solve them).
You can also think about where the trade-offs are when compared to a dynamic heap - performance, memory usage, etc.
As-written, your heap implementation doesn't sound like a good idea. Compare it with the one I've outlined above.
-Aaron