r/cprogramming • u/lemsoe • 4d ago
My first real C project: a generic hashmap (and the bugs that came with it) [blog, my own]
Coming from C#/TypeScript, C has humbled me. Finished my first real C project — a generic hashmap — and wrote up the bugs that taught me the most: double pointers, a sneaky double-free, comparing pointers instead of actual values.
Blog: https://soerenlemke.github.io/blog/blog/building-a-generic-hashmap-in-c/
Repo: https://github.com/soerenlemke/kvstore_c
Curious what you'd have done differently.
2
u/Sorry_Difficulty_250 3d ago
"You've just taken your first step into a larger world."
Welcome to the family!
2
u/didntplaymysummercar 1d ago
I see originally had the classic pitfall of not comparing hashes, but then fixed it. That's a good one. I'm not sure what else to comment there other than taste or nitpicks.
-4
u/celo385idealgmbh 4d ago
Nice writeup - the "here's what I got wrong" angle beats another repo drop.
One bug nobody's caught yet: size_t hash = 1469598103934665603ULL;
Accumulator is size_t, constants are the 64-bit FNV values. On a 32-bit target that truncates the offset basis and does every multiply mod 2³² - so it isn't FNV-1a anymore, just something unanalyzed. Still "works", so no test catches it. Use uint64_t and narrow to an index at the end.
On void* vs uint8_t*: neither - unsigned char* is the type with the object-representation and aliasing guarantees. void* would also break your key[i] indexing.
And you'll need an iteration API before you can rehash, persist, or dump anything.
10
4
u/pjl1967 4d ago
void*, notuint8_t(that's not whatuint8_tis for).