This is a custom dynamic memory allocator (malloc, free, calloc, realloc)
written in C from scratch. It is built to be portable across standard OS
environments (Linux) and bare-metal embedded systems (like STM32).
The allocator is built using a TDD (Test-Driven Development) workflow, is fully tested with the Unity framework, and is validated for memory safety with Valgrind.
The allocator is designed to be portable and can be compiled to use:
- A static array (ideal for bare-metal STM32/embedded projects).
sbrk()(for traditional Unix-like heap management).mmap()(for modern OS-level memory mapping).
- Configurable Backends: The heap memory source can be selected at compile time (
STATIC,SBRK, orMMAP) using a CMake option. - STM32 Linker Script Support: The
STATICheap is placed in a__attribute__((section(".my_heap"))), allowing an STM32 linker script (.ld) to place the heap in a specific memory region (e.g., CCM RAM). - Docker Environment: Includes a
Dockerfilefor a 100% reproducible build and test environment identical to the CI. - Robust CI/CD: Automated checks via GitHub Actions for formatting (
clang-format), static analysis (cppcheck), building, and memory leak/error checking (valgrind).
- Explicit Free List: Manages free memory using a singly-linked list.
- First-Fit Strategy: Scans the free list and uses the first block that is large enough.
- Block Splitting: Splits large free blocks to reduce internal fragmentation.
- Forward Coalescing:
my_freemerges a freed block with the next physical block if it is also free. - Memory Alignment:
my_mallocreturns memory aligned to 8 bytes. - Robust Safety Checks:
- Magic Numbers (
0xC0FFEE): Validates block headers to detect corruption. - Boundary Checks:
my_freevalidates pointers against heap bounds. - Double-Free Protection:
my_freedetects and ignores attempts to free an already-freed block.
- Magic Numbers (
- Full API: Implements
my_malloc,my_free,my_calloc, andmy_realloc. - Testing: Includes a full unit test suite (18 tests) using the Unity framework.
This project follows a clean, professional, and scalable directory structure:
.
├── .github/
│ └── workflows/
│ └── ci.yml
├── .clang-format
├── .gitignore
├── CMakeLists.txt
├── Dockerfile
├── Doxyfile
├── LICENSE
├── README.md
├── assets/
│ ├── output.gif
│ └── ci.png
├── build/ # CMake build output
├── demo/
│ ├── CMakeLists.txt
│ └── main.c
├── docs/ # Doxygen-generated documentation
│ └── (Doxygen output)
├── include/
│ └── my_allocator.h
├── src/
│ └── my_allocator.c
├── tests/
│ ├── CMakeLists.txt
│ └── test_main.c
└── vendor/
└── unity/ # Unity test framework
| Category | Tool/Standard |
|---|---|
| Language | C (C11) |
| Build System | CMake |
| Testing | Unity |
| Code Style | clang-format (LLVM) |
| Static Analysis | cppcheck |
| Memory Debugging | Valgrind |
| Documentation | Doxygen |
| CI/CD | GitHub Actions |
| Environment | Docker (Ubuntu 22.04) |
| Version Control | Git (Feature Branch & PR Workflow) |
This project can be built natively on Linux or within the provided Docker container.
This is the easiest and most reliable way to build, as it matches the CI environment.
- Build the image:
docker build -t heap-engine-dev . - Run the build & tests (example using MMAP backend):
docker run --rm -v "$(pwd)":/app heap-engine-dev \ /bin/bash -c "rm -rf build && \ cmake -S . -B build -DHEAP_BACKEND=3 && \ cmake --build build && \ ./build/tests/run_tests && \ valgrind ./build/demo/allocator_demo"
- Install Prerequisites:
sudo apt update && sudo apt install -y build-essential cmake valgrind - Clone the Repository:
git clone [https://github.com/surajgajavelly/HeapEngine.git](https://github.com/surajgajavelly/HeapEngine.git) cd HeapEngine - Configure CMake (Select Backend):
# To build with the default STATIC backend (for STM32 or general use): cmake -S . -B build # To build with the SBRK backend: cmake -S . -B build -DHEAP_BACKEND=2 # To build with the MMAP backend: cmake -S . -B build -DHEAP_BACKEND=3
- Build the project:
cmake --build build
After building, you can run the unit tests and the demo application.
-
Run Unit Tests:
./build/tests/run_tests
-
Run Demo Application (with Valgrind):
valgrind --leak-check=full --show-leak-kinds=all ./build/demo/allocator_demo
A successful run will show
ERROR SUMMARY: 0 errorsandAll heap blocks were freed.
- Backward Coalescing: Implement full two-way coalescing (merging with the previous block) by adding footers/boundary tags.
- Thread-Safety: Add mutexes to protect the free list for use in an RTOS.
- Dynamic Growth: Enhance the
SBRK/MMAPbackends to request more memory from the OS if the free list is exhausted.
Contributions are what make the open-source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature) - Commit your Changes (
git commit -m 'feat: Add some AmazingFeature') - Push to the Branch (
git push origin feature/AmazingFeature) - Open a Pull Request
Distributed under the MIT License. See LICENSE for more information.

