A custom, thread-safe memory allocator written in C from scratch. AllocFast serves as a drop-in educational replacement for the standard library's malloc and free, built directly on top of UNIX system calls (mmap).
AllocFast implements custom memory management logic with multiple configurable allocation strategies. It features:
- Multiple Allocation Strategies: Supports First-Fit, Best-Fit, and Segregated List (SLUB-like) allocation patterns.
- Thread Safety: Fully synchronized using
pthreadmutexes to allow safe concurrent allocations across multiple threads. - Memory Protection (Red Zones): Implements automated buffer overflow and underflow detection by padding allocations with "magic bytes" (0xAA). If a program writes outside its allocated bounds,
my_freewill catch the corruption and safely abort. - Micro-Benchmarking: Includes an integrated benchmark suite to compare the speed of different allocation strategies against glibc's native
mallocandfree.
I built this project to deepen my understanding of systems programming, operating system internals, and memory management. By bypassing the standard library and requesting memory pages directly from the kernel, this project served as a hands-on exploration of:
- Heap fragmentation and coalescing.
- Performance trade-offs between different search algorithms (First-Fit vs. Best-Fit).
- Concurrency controls and race conditions in low-level memory handling.
- Debugging tools and security mechanisms like Valgrind-style red zones.
AllocFast bypasses the standard library and uses mmap to request memory directly from the kernel. It supports multiple allocation strategies and uses red zones to detect memory corruption.
This diagram illustrates how allocations are routed through the custom thread-safe allocator:
flowchart TD
App([User Application]) --> |my_malloc / my_free| API[Public API]
subgraph AllocFast Memory Allocator
API --> Mutex{pthread_mutex}
Mutex --> |Lock| Core[Core Allocation Logic]
Core --> |Strategy Check| Router{AllocStrategy}
Router --> |STRATEGY_FIRST_FIT| FF[First-Fit Search]
Router --> |STRATEGY_BEST_FIT| BF[Best-Fit Search]
Router --> |STRATEGY_SEGREGATED| SL[Segregated List Search]
FF --> GlobalFree[(Global Free List)]
BF --> GlobalFree
SL --> SegLists[(Segregated Lists Array)]
GlobalFree --> Miss[Cache Miss / No Block Found]
SegLists --> Miss
GlobalFree --> Hit[Block Found]
SegLists --> Hit
Miss --> SysCall[request_memory]
Hit --> Split[Split Block & Update Lists]
SysCall --> Security[Apply Security Measures]
Split --> Security
Security --> |Write 0xAA Red Zones| MutexUnlock{pthread_mutex_unlock}
end
SysCall --> |mmap anonymous pages| OS[(UNIX Kernel)]
MutexUnlock --> Return([Return Payload Pointer])
classDef memory fill:#f9f,stroke:#333,stroke-width:2px;
class OS,GlobalFree,SegLists memory;
This diagram shows the physical layout of a single allocated memory chunk, including the metadata node and the 0xAA security boundaries (Red Zones) used to catch buffer overflows.
classDiagram
class GlobalHeap {
+BlockMeta* global_base
+BlockMeta* global_tail
+BlockMeta* global_free_list
+BlockMeta*[11] segregated_lists
}
class BlockMeta {
<<Header / Metadata>>
+size_t size
+size_t exact_size
+bool is_free
+BlockMeta* next
+BlockMeta* prev
+BlockMeta* next_free
+BlockMeta* prev_free
}
class MemoryChunk {
<<Physical Memory Layout>>
+BlockMeta metadata
+char[8] front_redzone (0xAA)
+void* payload
+char[8] back_redzone (0xAA)
}
GlobalHeap "1" *-- "many" BlockMeta : tracks
BlockMeta "1" -- "1" MemoryChunk : resides directly before
The project is written in standard C11 and requires a POSIX-compliant environment (Linux/macOS) due to the use of mmap and pthread.
To compile the project with standard settings (recommended for debugging and development), run from the root directory:
mkdir -p build
gcc -std=c11 -Wall -Wextra -Iinclude -pthread src/allocator.c -o build/allocfastFor an optimized release build (which enables Link Time Optimization and strips debug symbols for maximum benchmark performance), run:
mkdir -p build
gcc -std=c11 -Wall -Wextra -O3 -flto -s -Iinclude -pthread src/allocator.c -o build/allocfastRunning the compiled executable will automatically execute the internal micro-benchmark suite, followed by a memory protection test.
./build/allocfastExpected Output:
- Benchmark Results: You will see a performance comparison of 50,000 allocations/frees using glibc, First-Fit, Best-Fit, and Segregated Fit.
- Normal Allocation Test: Verifies basic read/write persistence.
- Red Zone Test: The program will intentionally simulate a buffer overflow and deliberately crash with a
[FATAL ERROR] Overflow detectedmessage. This confirms the security boundaries are actively protecting memory.