summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorrofl0r <rofl0r@users.noreply.github.com>2021-03-14 16:06:10 +0000
committerrofl0r <rofl0r@users.noreply.github.com>2021-03-14 16:06:10 +0000
commitc4231e58bf2613b6ab8b34f234c117c5d1488931 (patch)
treecb8260ee0f6364fd1369948f1cfc591da203cf03
parent38934921c4d6801ebdc13d32b4238c4a2ffa9c98 (diff)
orderedmap: fix memory leak when using orderedmap_remove()
closes #351
-rw-r--r--src/hsearch.c8
-rw-r--r--src/hsearch.h2
-rw-r--r--src/orderedmap.c9
3 files changed, 17 insertions, 2 deletions
diff --git a/src/hsearch.c b/src/hsearch.c
index d8d395a..70d757a 100644
--- a/src/hsearch.c
+++ b/src/hsearch.c
@@ -156,6 +156,14 @@ htab_value* htab_find(struct htab *htab, const char* key)
return &e->item.data;
}
+htab_value* htab_find2(struct htab *htab, const char* key, char **saved_key)
+{
+ struct elem *e = htab_find_elem(htab, key);
+ if(!e) return 0;
+ *saved_key = e->item.key;
+ return &e->item.data;
+}
+
int htab_delete(struct htab *htab, const char* key)
{
struct elem *e = htab_find_elem(htab, key);
diff --git a/src/hsearch.h b/src/hsearch.h
index ec81cc3..7e9d770 100644
--- a/src/hsearch.h
+++ b/src/hsearch.h
@@ -14,6 +14,8 @@ typedef union htab_value {
struct htab * htab_create(size_t);
void htab_destroy(struct htab *);
htab_value* htab_find(struct htab *, const char* key);
+/* same as htab_find, but can retrieve the saved key (for freeing) */
+htab_value* htab_find2(struct htab *htab, const char* key, char **saved_key);
int htab_insert(struct htab *, char*, htab_value);
int htab_delete(struct htab *htab, const char* key);
size_t htab_next(struct htab *, size_t iterator, char** key, htab_value **v);
diff --git a/src/orderedmap.c b/src/orderedmap.c
index 4902be0..1818e27 100644
--- a/src/orderedmap.c
+++ b/src/orderedmap.c
@@ -81,14 +81,19 @@ char* orderedmap_find(struct orderedmap *o, const char *key) {
int orderedmap_remove(struct orderedmap *o, const char *key) {
size_t i;
char *lk;
- htab_value *lv, *v = htab_find(o->map, key);
+ char *sk;
+ char **sv;
+ htab_value *lv, *v = htab_find2(o->map, key, &sk);
if(!v) return 0;
- htab_delete(o->map, key);
+ sv = sblist_get(o->values, v->n);
+ free(*sv);
sblist_delete(o->values, v->n);
i = 0;
while((i = htab_next(o->map, i, &lk, &lv))) {
if(lv->n > v->n) lv->n--;
}
+ htab_delete(o->map, key);
+ free(sk);
return 1;
}