std.StringHashMap example: Why do I need to manage memory of key and not value?

Newbie still working on understanding memory issues.

Looking at this example which uses a HashMap([]const u8,User,StringContext)). The explanation is clear why I need to manage the memory of the key - the key is a string that is temporarily created and freed within each loop (I assume Zig compiler does this via the stack). Once the loop terminates, it is not unavailable.

Why is it I do not have to do the same with the value when I do a put? Is it copied (could not understand library code to check this)? Isn’t the value in the loop also temporary? I am assuming that to use value pointer, I need only change:

std.StringHashMap(User)

to

std.StringHashMap(*User)

so I can also manage the lifetime of these values.

TIA,
HF

When you call put all that happens is that the map copies the value you’ve supplied into its internal storage (source code). That means that, if your values are strings or some other kind of pointer, only the pointer will be stored by the map and the underlying data will not be copied.
So you’re correct, all you’d have to do to be in charge of storing all Users yourself is to change the value type to a pointer to User.

4 Likes

@Justus2308 Thanks for taking the time to search the code and explain. Need to remember that copying a string pointer is not copying its contents. Thanks again.

1 Like

To stress the point a bit, keys and values are the same here: the HashMap will copy what you give it.

Slices are ‘fat pointers’: a pointer with a length. So if you use a ‘string’ as a key or a value, that’s what gets copied, and the HashMap won’t deallocate the pointed-to memory when deinitialized.

If you used, say, a struct with no pointers as a key, that would also be copied, and therefore the copy would be freed with the HashMap.

3 Likes