02 / SYSTEMS
C-DSA Engine — Low-Level Memory-Managed Data Structures
A systems programming library implementing dynamic vectors, linked lists, and hash tables from scratch in C with strict manual heap control and O(n) complexity bounds.
overview
First-Principles Data Structures & Manual Heap Management
This systems engineering project implements foundational computer science data structures—including dynamic growable vectors, doubly-linked lists, and collision-resolved hash tables—entirely from scratch in standard C.
Rather than relying on high-level language abstractions or garbage-collected runtimes, the codebase exercises explicit control over virtual address spaces, pointer arithmetic, stack versus heap allocation, and lifecycle memory reclamation.
The architecture is engineered to guarantee that destructive operations such as node deletions, sequential traversals, and dynamic array resizing strictly adhere to worst-case O(n) time complexity bounds while preventing memory fragmentation and leaks.
the problem
Abstraction Overhead & Memory Vulnerabilities
High-level programming runtimes obscure how memory is actually laid out in physical and virtual RAM, hiding cache locality inefficiencies and allocation overhead.
Improperly managed custom data structures frequently lead to dangling pointers, buffer overflows, catastrophic memory leaks, or unoptimized $O(n^2)$ lookup storms.
Systems engineers require predictable memory footprints and deterministic execution times, necessitating absolute control over heap allocation primitives like malloc and realloc.
the approach
Explicit Heap Lifecycle Control & Algorithmic Bounds
Design custom struct abstractions backed by raw byte pointers, manually allocating heap memory via malloc and handling capacity expansions through geometric realloc scaling factors.
Implement rigorous reference and pointer decoupling protocols during node deletions in linked lists and hash buckets, ensuring instant memory freeing via free() to eliminate dangling references.
Enforce strict algorithmic complexity invariants across all operations, guaranteeing that search, insertion, and deletion paths never exceed O(n) worst-case time complexity.
the build
From interface to infrastructure
Dynamic Vector Allocation
Engineered a growable array supporting O(1) amortized insertions, utilizing realloc to double buffer capacity upon reaching high load thresholds while maintaining contiguous memory blocks for optimal CPU cache hits.
Linked List Node Lifecycle
Built a doubly-linked list module featuring O(1) head/tail insertions and strict O(n) search and targeted node removal, immediately invoking free() on deleted nodes to reclaim heap memory without leaks.
Hash Table Collision Resolution
Implemented an in-memory key-value hash table utilizing separate chaining with linked lists to handle hash collisions, bounded by O(n) worst-case lookup and deletion complexities.
highlights
The parts that make the product work.
Explicit Heap Memory Management
Zero garbage collection dependency; every byte allocated on the heap is explicitly tracked, resized via realloc, and freed upon teardown.
Strict Complexity Bounds
Guaranteed worst-case O(n) time complexity for targeted node deletions and searches, preventing algorithmic degradation.
Valgrind Memory Verification
Rigorously tested and verified under Valgrind to ensure zero memory leaks, invalid reads, or uninitialized pointer dereferences.
engineering
The decision behind the product.
Amortized Growth via Realloc
When vector capacity is exhausted, the allocator issues a realloc request with a 2x geometric growth factor, reducing system call overhead and amortizing insertion costs to O(1).
Safe Pointer Deallocation
Node deletion routines isolate target pointers, patch surrounding neighbor links in O(1) pointer-rewiring time, and execute immediate free() to return memory blocks to the OS heap allocator.
in the product
A closer look.

reflection
What I learnt from building it.
Building these data structures from scratch in C deepened my mastery of memory mechanics, pointer dereferencing, and heap fragmentation dynamics.
Managing malloc and realloc manually taught me to anticipate edge cases like allocation failures and out-of-memory (OOM) signals at the system level.
This foundational understanding of memory layout directly informs how I design high-performance data flow and state structures in higher-level web frameworks.