how to free mem?
i found that hashmap_free do not work, the mem can not free and with the time going on, the mem will reach very high, so what can i do?
TLDR
If you are allocating memory to your struct item (using malloc or related functions), you can free that memory after you call hashmap_set(hashmap, item).
At the end of this comment, I've included a source code with its output, for reference.
Long Version
I looked at the hashmap implementation, I'll try to explain what I've understood.
Hashmap Memory Structure
-
Memory allocated to the hashmap is:
sizeof(struct hashmap) + (2 * map->bucketsz))map->bucketsz = sizeof(struct bucket) + sizeof(struct item), whereitemis the struct you want to insert into the hashmap. -
The reason why an additional
2 * map->bucketszspace is allocated to the hashmap is because it is used internally by the hashmap when their functions get called. One is for temporary storagehash->spare(like how a temp variable is used when you want to swap 2 variables), and anotherhash->entry, for initially storing theitemwhenhashmap_set()is called. -
The
bucket_itemstruct (refer to diagram, this is something I named - it is not in the source code), holds astruct bucket(containing the hash) andstruct item(your item struct). -
The memory allocated to
hashmap->bucketsis equal tonbucket_items, wheren = hashmap->nbuckets.
Inserting an item into the hashmap
-
When
hashmap_set()orhashmap_set_with_hash()is called, the bucket hash is calculated. The bucket structure and youritemstruct get copied (using memcpy) intohashmap->edata. (This is the point where you can free memory allocated toitem, because it was copied). -
The bucket index is calculated by taking the some LSB bits of the hash (the number of bits depends on
map->mask, which ismap->nbuckets - 1). This thebucket_itemwhere theitemwill be stored, i.e., copied into the bucket_item from the entry bucket. PS: I won't be explaining what happens when a collision occurs, I just wanted to explain thatitemgets copied into one of the bucket_items.
What happens when hashmap_free() or hashmap_clear() is called?
-
For every bucket,
hashmap->elfree()is called, which is the free function passed tohashmap_create(). NOTE: If you have allocated memory to youritembefore inserting to the hashmap (hashmap_set()orhashmap_set_with_hash()), this memory will not get freed whenhashmap_free()orhashmap_clear()is called. It only frees theitemstruct present in the bucket_item. -
Memory to
hashmap->bucketsandhashmapget freed.
Example code and output which does not result in memory leak
Source code: https://p.ip.fi/9jq6 Valgrind output:
$ valgrind --leak-check=full build/main
==6395== Memcheck, a memory error detector
==6395== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==6395== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==6395== Command: build/main
==6395==
string: 123456789
==6395==
==6395== HEAP SUMMARY:
==6395== in use at exit: 0 bytes in 0 blocks
==6395== total heap usage: 5 allocs, 5 frees, 1,650 bytes allocated
==6395==
==6395== All heap blocks were freed -- no leaks are possible
==6395==
==6395== For counts of detected and suppressed errors, rerun with: -v
==6395== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Sorry for the long explanation, I probably explained a lot of stuff unrelated to the issue.