aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTucker Evans <tucker@tuckerevans.com>2020-07-06 20:07:45 -0400
committerTucker Evans <tucker@tuckerevans.com>2020-07-08 11:02:44 -0400
commit7d69ea177200bda62b403eb9ead6eee2ba5abe52 (patch)
treecad2e1fd9810ca300d7219230aa1819ce1ff11f2
parent51d368c20e1d93970a94cb0d2aff10654922bb37 (diff)
Add reset key function for maps
Allows changing the pointer to key when they are equivalent (by cmp function), to avoid memory leaks that could happen if we assumed either pointer was to be freed or overwritten.
-rw-r--r--collections/map/map.adoc23
-rw-r--r--collections/map/map.c23
-rw-r--r--collections/map/map.h1
3 files changed, 46 insertions, 1 deletions
diff --git a/collections/map/map.adoc b/collections/map/map.adoc
index 2b3e2cb..2822b79 100644
--- a/collections/map/map.adoc
+++ b/collections/map/map.adoc
@@ -1,7 +1,7 @@
Map
===
Tucker Evans
-v0.3, 2020-07-06
+v0.4, 2020-07-06
A basic map implemented in an AVL tree.
@@ -92,6 +92,27 @@ map_insert(dict, "ONE", NULL);
assert(map_size(dict) == 1);
----
+[[map_reset_key]]
++void* map_reset_key(map *self, vaid *key)+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+This replaces an equivalent key with the one passed in, the key that is
+overwritten is return so the user can free it.
+
+Examples
+^^^^^^^^
+[source,c]
+----
+#include "map.h"
+#include <string.h>
+
+map *dict = map_new((cmp_func) strcmp);
+
+map_insert(dict, strdup("ONE"), "VALUE");
+assert(map_insert(dict, "ONE", "NEW_VALUE") < 0);
+free(map_reset_key(dict "ONE"));
+assert(map_insert(dict, "ONE", "NEW_VALUE") == 0);
+----
+
[[map_clear]]
+void map_clear(map *self)+
~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/collections/map/map.c b/collections/map/map.c
index 83a446d..7de58e4 100644
--- a/collections/map/map.c
+++ b/collections/map/map.c
@@ -82,6 +82,29 @@ void *key, *val;
return 0;
}
+void* map_reset_key(root, key)
+map *root;
+void *key;
+{
+ void *tmp;
+ int cmp;
+
+ if (!root || !key)
+ return NULL;
+
+ cmp = root->cmp(root->key, key);
+
+ if (cmp < 0)
+ return map_reset_key(root->left, key);
+
+ if (cmp > 0)
+ return map_reset_key(root->right, key);
+
+ tmp = root->key;
+ root->key = key;
+ return tmp;
+}
+
void map_clear(root)
map *root;
{
diff --git a/collections/map/map.h b/collections/map/map.h
index b389d87..a5fc816 100644
--- a/collections/map/map.h
+++ b/collections/map/map.h
@@ -12,6 +12,7 @@ int map_size(map*);
/*data*/
int map_insert(map*, void*, void*);
+void* map_reset_key(map*, void*);
/*memory*/
void map_clear(map*);