Sprint 2: Data & Invariants - Expanded Projects

Sprint 2: Data & Invariants - Expanded Projects

Goal: Understand the hidden contracts that govern C programming—the unwritten rules that determine whether your program works correctly or descends into undefined behavior.

What You Will Internalize

  • What invariants are and why they’re the difference between “works on my machine” and “provably correct”
  • Who owns what memory and when it’s safe to use, modify, or free it
  • How data actually exists in memory (not as abstract types, but as bytes with alignment and padding)
  • When pointers are valid and when they’re time bombs waiting to explode
  • How to design defensively so your code fails loudly and obviously rather than silently corrupting data

Project Index

# Project Core Topics Difficulty Time
1 Safe Dynamic Array Library Invariants, Ownership, Bounds Checking, Amortized O(1) Intermediate 1 week
2 Text Editor Buffer (Gap Buffer) Memory Layout, Aliasing, Sentinel Values, memmove Advanced 1-2 weeks
3 Memory Arena Allocator Alignment, Ownership, Lifetime, Bulk Deallocation Advanced 1 week
4 JSON Parser with Explicit Ownership Recursive Ownership, Tree Structures, Representing Absence Advanced 2 weeks
5 Simple Linked List Database Iterator Invalidation, Defensive Design, CRUD Operations Advanced 1-2 weeks
6 HTTP Server with Request Pooling (Capstone) All Concepts Combined, Production-Grade Code Expert 2-4 weeks

The Five Pillars

1. Invariants — The Hidden Rules That Must Never Break

An invariant is a condition that must always be true at specific points in your program’s execution. It’s not a suggestion—it’s a contract that your code makes with itself.

2. Ownership — Every Byte Has Exactly One Master

Every allocated byte must have exactly one owner:

  • Too few owners (zero) → memory leak
  • Too many owners (two+) → double free or use-after-free

3. Memory Layout — Data Is Not Abstract; It’s Bytes with Rules

In C, data is bytes—and those bytes have very specific rules about where they can live and how they can be arranged.

4. Validity Windows — When Pointers Live and Die

A pointer has a lifetime—a window of time during program execution when dereferencing it is safe.

5. Defensive Design — Trust Nothing, Verify Everything

Assume everything will go wrong, and code accordingly. Fail loudly and early, not silently later.

  1. Start with Safe Dynamic Array (Week 1)
    • Foundation for all other projects
    • Invariants become intuitive
    • Ownership patterns established
  2. Then Gap Buffer (Week 2)
    • Applies invariants to real-world problem
    • Memory movement challenges
    • Performance considerations
  3. Then Memory Arena (Week 3)
    • Alternative ownership model
    • Alignment requirements
    • Bulk deallocation pattern
  4. Then JSON Parser (Week 4)
    • Recursive ownership
    • Complex invariants
    • Real-world data format
  5. Then Linked List Database (Week 5)
    • Iterator invalidation
    • Defensive design in practice
    • Persistence considerations
  6. Capstone: HTTP Server (Week 6+)
    • All concepts combined
    • Production-grade implementation
    • Real-world testing

Essential Books

Priority Book Key Contribution
⭐⭐⭐ “Effective C” by Robert Seacord Modern, comprehensive C programming
⭐⭐⭐ “Writing Solid Code” by Steve Maguire Defensive programming wisdom
⭐⭐⭐ “C Interfaces and Implementations” by David Hanson Design-by-contract philosophy
⭐⭐ “Computer Systems: A Programmer’s Perspective” Memory layout understanding
⭐⭐ “The Practice of Programming” Debugging and testing
“Expert C Programming” by Peter van der Linden Deep C insights

Concept-to-Project Mapping

Project Primary Concepts
Dynamic Array Invariants, Ownership, Bounds Checking
Gap Buffer Memory Layout, Aliasing, Sentinel Values
Arena Allocator Ownership, Alignment, Lifetime
JSON Parser Ownership Transfer, Representing Absence, Defensive Design
Linked List DB Invariants, Iterator Validity, Defensive Checks
HTTP Server All concepts combined

Total Estimated Time: 6-8 weeks of focused study

After completion: You will write code that is not just “working” but trustworthy—code you can reason about, debug systematically, and deploy with confidence.