Live data from Hacker News

How to implement a hash table in C (2021)

benhoyt.com

11–20 of 43 posts

Re: How to implement a hash table in C (2021)

#11
post #3

It's the ihih guy! Thanks for being one of the few C bloggers out there.

I enjoy reading posts about C just to see how much boilerplate and footguns higher languages let you avoid. I would like to write C, but I just have no trust I would remember or even know how to do things right (use `calloc` vs `malloc`, free the table when allocation of `entries` fails etc).

Re: How to implement a hash table in C (2021)

#13
post #11
post #3

It's the ihih guy! Thanks for being one of the few C bloggers out there.

I enjoy reading posts about C just to see how much boilerplate and footguns higher languages let you avoid. I would like to write C, but I just have no trust I would remember or even know how to do things right (use `calloc` vs `malloc`, free the table when allocation of `entries` fails etc).

The thing about boilerplate is that you were always rewriting it, so avoiding the footguns became habit.

(So ... which takes longer, writing the data structure you want, as we all did then, or searching for the perfect library, as some people do now?)

EDIT: awk(1) had built-in hash tables, and dates from 1977. Note that generic hashing becomes much more useful after D-space gets larger than 16-64k! (14-16 bits of address)

Re: How to implement a hash table in C (2021)

#14

There was a fantastic benchmark of C and C++ hash tables doing the rounds a few weeks ago, it's pretty fun reading: https://jacksonallan.github.io/c_cpp_hash_tables_benchmark/ . Unless I really didn't want to introduce dependencies, or reduce code size, I think I'd use an off the shelf hash table implementation these days. It's still a fun exercise building your own though.

One important consideration is missing from this benchmark: how they behave with multi-threading. There can be big differences between diffent hash table implementation when you have to use them from different threads (built-in smart thread safety vs external dumb locks, etc)

Re: How to implement a hash table in C (2021)

#15
post #7

I played around with C++ when I was at university. Then never touched it again. So, with a grin I stumble over things like "void* ht_get(...)" Wait. What? A void pointer? Interesting... I have no clue. I like articles like these. For someone not familiar with C it's a perfect level. In terms of explanation and the code itself.

It has no type, so you can cast it to whatever it actually is. Even a function you will call. The main use case is generic functions. And in data structures like this.

Casting between void pointers and function pointers is, strictly speaking, undefined behavior. Though it does tend to work, it's not something to rely on.

(And you don't need casts when converting between void pointers and data pointers)

Re: How to implement a hash table in C (2021)

#17

I really like the API design of libjudy for general hash table like interfaces. It prevents you from having to hash a key twice just to do "check if key is not present, then set value, otherwise leave original value in hash." The pattern also meshes better with the way iterators naturally work. Also, in terms of this table, if you add the computed key hash value to the stored hash entry, you can check that the value…

POSIX hsearch tables are terrible. There's a reason why nobody uses them.

One at a time per program, having to know how big the table needs to be at initialization time with no automatic resizing, an API that's very limited (no way to remove entries, iterate over entries, tell how many entries are in the table, ...)

Re: How to implement a hash table in C (2021)

#18
post #15
post #7

Earlier quoted context omitted.

It has no type, so you can cast it to whatever it actually is. Even a function you will call. The main use case is generic functions. And in data structures like this.

Casting between void pointers and function pointers is, strictly speaking, undefined behavior. Though it does tend to work, it's not something to rely on. (And you don't need casts when converting between void pointers and data pointers)

AFAIK it's undefined behaviour in ISO C, but not so in POSIX.

Re: How to implement a hash table in C (2021)

#19
post #17

I really like the API design of libjudy for general hash table like interfaces. It prevents you from having to hash a key twice just to do "check if key is not present, then set value, otherwise leave original value in hash." The pattern also meshes better with the way iterators naturally work. Also, in terms of this table, if you add the computed key hash value to the stored hash entry, you can check that the value…

POSIX hsearch tables are terrible. There's a reason why nobody uses them. One at a time per program, having to know how big the table needs to be at initialization time with no automatic resizing, an API that's very limited (no way to remove entries, iterate over entries, tell how many entries are in the table, ...)

> One at a time per program

Reentrant versions have existed for quite some time.

> having to know how big the table needs to be at initialization time with no automatic resizing

The posted implementation resizes by creating an entirely new table and then moving all entries. The exact same mechanism is available with hsearch.

> no way to remove entries, iterate over entries

Strong downside but the posted implementation has no removal function either. It also leaks key memory on resize and free. It's iterator would need modification to allow delete during iteration.

> tell how many entries are in the table

somewhat_reasonable_point++;

Re: How to implement a hash table in C (2021)

#20
post #10

I played around with C++ when I was at university. Then never touched it again. So, with a grin I stumble over things like "void* ht_get(...)" Wait. What? A void pointer? Interesting... I have no clue. I like articles like these. For someone not familiar with C it's a perfect level. In terms of explanation and the code itself.

This is a bit of a pet peeve with anonymous Internet writing, but: are we supposed to know when you were at university? Do you know when I was? Why not state something like the number of decades or whatever? And yeah, a void * is how you express pointer to data of unknown type in C.

> This is a bit of a pet peeve with anonymous Internet writing, but: are we supposed to know when you were at university? Do you know when I was? Why not state something like the number of decades or whatever?

Does it matter? I tend to read it as "haven't touched it/had any use for it since university".

Post reply on HN