diff options
author | Nick Alcock <nick.alcock@oracle.com> | 2020-06-02 21:48:12 +0100 |
---|---|---|
committer | Nick Alcock <nick.alcock@oracle.com> | 2020-07-22 17:57:43 +0100 |
commit | 5ceee3dba3422bc8de49768c0c2d8f2608672fe7 (patch) | |
tree | c01783365add08aecbc1da2e122fd5dedf2aacd6 /libctf/ctf-hash.c | |
parent | 809f6eb3321edb91fcc96b1f8353dbfe2f762fa7 (diff) | |
download | binutils-5ceee3dba3422bc8de49768c0c2d8f2608672fe7.zip binutils-5ceee3dba3422bc8de49768c0c2d8f2608672fe7.tar.gz binutils-5ceee3dba3422bc8de49768c0c2d8f2608672fe7.tar.bz2 |
libctf, hash: improve insertion of existing keys into dynhashes
Right now, if you insert a key/value pair into a dynhash, the old slot's
key is freed and the new one always assigned. This seemed sane to me
when I wrote it, but I got it wrong time and time again. It's much
less confusing to free the key passed in: if a key-freeing function
was passed, you are asserting that the dynhash owns the key in any
case, so if you pass in a key it is always buggy to assume it sticks
around. Freeing the old key means that you can't even safely look up a
key from out of a dynhash and hold on to it, because some other matching
key might force it to be freed at any time.
In the new model, you can always get a key out of a dynhash with
ctf_dynhash_lookup_kv and hang on to it until the kv-pair is actually
deleted from the dynhash. In the old model the pointer to the key might
be freed at any time if a matching key was inserted.
libctf/
* ctf-hash.c (ctf_hashtab_insert): Free the key passed in if
there is a key-freeing function and the key already exists.
Diffstat (limited to 'libctf/ctf-hash.c')
-rw-r--r-- | libctf/ctf-hash.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/libctf/ctf-hash.c b/libctf/ctf-hash.c index 4696fcb..1c37d75 100644 --- a/libctf/ctf-hash.c +++ b/libctf/ctf-hash.c @@ -171,15 +171,15 @@ ctf_hashtab_insert (struct htab *htab, void *key, void *value, *slot = malloc (sizeof (ctf_helem_t)); if (!*slot) return NULL; + (*slot)->key = key; } else { if (key_free) - key_free ((*slot)->key); + key_free (key); if (value_free) value_free ((*slot)->value); } - (*slot)->key = key; (*slot)->value = value; return *slot; } |