Fixed Memory Allocator
A C++ class implementing a page-chained memory allocator (Alloc, CAlloc, ReAlloc, Free) over a single fixed-size virtual memory block.
CFixedMemory is the in-memory sibling of the file-mapped allocator: instead of mapping a file it reserves one large VirtualAlloc block and runs the same first-fit, page-chain allocation strategy over it. Multi-page allocations are linked as chains with per-page attribute flags (USED, STARTOFCHAIN, ENDOFCHAIN, MANAGER), so ReAlloc can extend a chain in place when the following pages happen to be free, or relocate the data otherwise.
Use it when you want a self-contained heap inside your own process - for example an arena that survives library unload/reload, a sandboxed buffer pool, or just to study how a simple paging allocator works end to end. The Test() method exhausts the pool with uniform and non-uniform sizes, frees everything, then writes and re-reads every byte to verify integrity.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma once
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*
Memory mapping & handing routines.
*/
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define MEMORY_DEFAULT_PAGE_SIZE 128ul //Memory allocation granularity.
#define MEMORY_PAGE_ATTRIB_USED 0x1u //Pages that are allocated.
#define MEMORY_PAGE_ATTRIB_STARTOFCHAIN 0x2u //Pages that are allocated.
#define MEMORY_PAGE_ATTRIB_ENDOFCHAIN 0x4u //Pages that are the tail of a "chain" of pages.
#define MEMORY_PAGE_ATTRIB_MANAGER 0x8u //Pages that are used by the memory manager itsself.
typedef struct _tag_Memory_Manager_Info {
unsigned char *uAttribs; //Array of page attributes.
size_t uUsed; //The number of pages that have been allocated (count of non-free pages).
size_t uCount; //The total number of memory manager pages (([Total Mamory] - [Kernel Reserved]) / [Allocation Granularity]).
size_t uManagerPages; //The number of pages reserved my the memory manager for its internal use.
size_t uSize; //Number of bytes in each page.
size_t uBaseAddress; //The base address for all allocations.
} MEMORYMANAGERPAGES, *LPMEMORYMANAGERPAGES;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class CFixedMemory {
public:
void *CAlloc(size_t uBytes);
void *CAlloc(size_t uElementCount, size_t uElementSize);
void *Alloc(size_t uBytes);
void *Alloc(size_t uElementCount, size_t uElementSize);
void *ReAlloc(void *pAddress, size_t uTotalBytes);
bool Free(void *pAddress);
int FreeAll(void);
CFixedMemory();
CFixedMemory(size_t uiTotalRam);
CFixedMemory(size_t uiTotalRam, size_t uiPageSize);
~CFixedMemory();
bool Initialize(size_t uiTotalRam);
bool Initialize(size_t uiTotalRam, size_t uiPageSize);
void Destroy();
void GetPageInfo(MEMORYMANAGERPAGES *pMMP);
bool Test(void);
MEMORYMANAGERPAGES *Pages;
private:
void *AllocP(size_t uBytes, unsigned char uAttributes);
void *AllocP(size_t uElementCount, size_t uElementSize, unsigned char uAttributes);
void *ReAllocP(void *pAddress, size_t uTotalBytes, unsigned char uAttributes);
void *pBaseMemAddress; //Base of system memory.
};
The driver is minimal - reserve ten megabytes, run the built-in test, done:
#include <Windows.h>
#include <STDIO.h>
#include <STDLIB.h>
#include "CFixedMemory.H"
int main(int argc, char *argv[])
{
CFixedMemory mem;
mem.Initialize(1024 * 1024 * 10);
mem.Test();
return 0;
}
The implementation mirrors the file-mapped variant almost line for line: Initialize lays the MEMORYMANAGERPAGES structure at the front of the block, reserves enough pages for the per-page attribute array, and marks them MANAGER; AllocP scans forward counting contiguous free pages until it finds enough, flags the run with STARTOFCHAIN/ENDOFCHAIN, and returns the pointer; Free walks to the end of the chain clearing flags; ReAllocP extends in place or allocates-copies-frees. See the File Mapped Memory Allocator article for those bodies in full - only the backing store differs here.