Capstone — Building a Small Project
Twenty chapters, one piece at a time. This closing chapter builds kvstore — a real, persisted, command-line key-value store — combining structs, a hand-built hash table, dynamic memory, file I/O, and a genuine multi-file Makefile build into one working program.
The Project — A Persistent Key-Value Store
Every value survives between runs — loaded from disk on startup, saved back after any change.
The Data Structure
c3-2's hash table, reused directly — buckets of linked key-value pairs, separate chaining for collisions.
Reading & Writing Persistence
c2-6's File I/O — a simple text format, one key=value per line, loaded on startup and rewritten after every mutation.
The CLI Interface
c1-5's functions and c1-8's string handling, applied to argv.
Memory Management Throughout
Every key and value is duplicated onto the heap when inserted — c2-2's discipline, applied consistently end to end: freed on delete, and freed entirely on program exit, matching c3-2's own free_list-style traversal, now applied per bucket.
Structuring the Project With a Makefile
Split into hashtable.c/.h, storage.c/.h, and main.c — c2-5's real multi-file discipline, with a Makefile tying it all together.
Where Each Piece Came From
| Piece | Chapter |
|---|---|
| Hash table + separate chaining | c3-2 |
| File save/load format | c2-6 |
| CLI argument parsing, string comparison | c1-5, c1-8 |
| malloc/free discipline for every key/value | c2-2 |
| Multi-file build, Makefile | c2-5 |
| Verified with valgrind/ASan during development | c2-3, c3-5 |
What's Still Out of Scope, Honestly
kvstore is not thread-safe — no locking (c3-3) protects concurrent access to the file or the hash table. Values are plain strings only, not arbitrary binary data. There's no recovery logic for a corrupted save file. And no automated test suite or CI pipeline is wired up in this chapter itself, even though valgrind/ASan were used manually during development — a real next step, not something this capstone claims to have solved.
Closing the Course & Track
From c1-1's compile-then-link model to a real, persisted, multi-file program — every chapter in between added one specific piece of manual control C leaves entirely to the programmer, and one specific comparison to what Rust's compiler enforces instead. Twenty-one chapters, one throughline: C trusts you completely. Understanding exactly what that trust costs, and exactly what a compiler-enforced alternative buys back, is the actual lesson this entire track was built to teach.
Coding Challenges
Identify which specific chapter each of the following pieces of kvstore came from: (a) the separate-chaining collision strategy, (b) the save-file format, (c) the discipline of freeing every key and value on program exit.
📄 View solutionExplain why kvstore, as described in this chapter, is not safe if two instances of it are run concurrently against the same kvstore.db file — name the specific chapter's material that would need to be applied to fix this.
📄 View solutionAcross the entire 21-chapter C track, name the single idea that recurs most often, and explain in your own words why understanding it deeply matters more than memorizing any individual function or syntax rule.
📄 View solutionChapter 6 Quick Reference — Course & Track Complete
kvstorecombines: hash table (c3-2), file persistence (c2-6), CLI parsing (c1-5/c1-8), malloc/free discipline (c2-2), and a real Makefile build (c2-5)- Still out of scope, honestly: thread safety, binary values, corrupted-file recovery, automated testing
- Every discipline from Chapter 1 onward still applies at capstone scale — nothing gets relaxed
- Course 3 complete — C Advanced, 6 chapters
- Full C track complete — Fundamentals + Intermediate + Advanced, 21 chapters across 3 courses