Introduction
Dynamic memory management is much useful in application development, reliable and fast are key points to this kind of library. This source code of this library is very small and it provides API in the same form as stdlib does.
Interface
- HANDLE InitializeMemoryPartition(void *base, DWORD size);
Initialize a new heap memory partition - void *AllocateMemory(HANDLE hMem, DWORD size);
Allocate a new memory block in specified partition - void *ResizeMemory(HANDLE hMem, void *p, DWORD newSize);
Reallocate a new size for an existing block - void FreeMemory(HANDLE hMem, void *p);
Release a memory block - bool QueryMemoryInformation(HANDLE hMem, DWORD *total, DWORD *used);
Query information of memory partition
Mechanism
- Chunk
Chunk is memory block. Every allocated block is a chunk with a chunk header filled up at the first of its buffer. All chunks are linked in a list.
The definition of chunk header is:
typedef struct TChunkHdr { UINT iMagicNumber; // magic number UINT nChunks; // size of chunk in chunks DWORD dwAllocatedSize; // allocated size in bytes TChunkHdr *pNextChunk; // next chunk in the list } TChunkHdr;
- Initialize memory partition
The number of partitions application can create depends on the definition of partition in source code. It could be any number larger than zero. When create a memory partition, a allocated base buffer and size should be provided, the header of buffer will be filled up with a initial chunk header which owns the whole size of buffer.
typedef struct TMemoryPartition { UINT iMagicNumber; DWORD dwTotalSize; DWORD dwAllocatedSize; UINT nMaxChunks; UINT nTotalBlocks; TChunkHdr *pFirstChunk; // first memory chunk pointers HANDLE hMutex; // mutex for memory operation } TMemoryPartition;
- Allocate memory
When application call AllocateMemory to allocate a memory block, this routine will go through the linked list of chunks to find a free block which has enough space, and create a new block at the end of that block, insert the new created block between the original block and its next chunk in the linked list. - Release memory
When an allocated block was released, the next chunk linked with it will also be released and merge them into a bigger free block. - Resize memory
We need this function because we do not need to really allocate a new memory block if the current block size is bigger than the size wanted. Allocating a new block of memory will cause high cost of CPU time.
Usage
- This simple example shows the basic usage of this library, it creates a memory heap with 32M size.
void usage() { static BYTE buffer[32 * 1024 * 1024]; HANDLE hMem = ::InitializeMemoryPartition(buffer, sizeof(buffer)); void *p = ::AllocateMemory(hMem, 100); ::FreeMemory(hMem, p); }