<cxo />

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.

    C-DSA Engine — Low-Level Memory-Managed Data Structures screenshot 01

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.