Yesterday I was discussing a bug in some code using a GHashTable with Will and we both started to wonder if there is any reason to use g_hash_table_insert
instead of g_hash_table_replace
.
First of all an example, look at this code and try to find the bug.
#include <glib.h> static void add_entry (GHashTable *ht, const gchar *config) { gchar **split_config = g_strsplit (config, "=", 2); if (g_strv_length (split_config) == 2) { gchar *key = g_utf8_strdown (split_config[0], -1); gchar *value = g_strdup (split_config[1]); g_hash_table_insert (ht, key, value); g_print ("Set %s to %sn", key, value); } g_strfreev (split_config); } int main (int argc, char **argv) { GHashTable *ht = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); gint i; for (i = 1; i < argc; i++) add_entry (ht, argv[i]); g_hash_table_unref (ht); return 0; }
If it’s not clear where the bug is, try invoking the program with “apples=42 Pears=12 APPLES=10
” on the command line.
If a key already exists in the hash table, the key passed to g_hash_table_insert
is destroyed and you cannot use it afterwards. This behaviour is documented, but it’s easy to find code affected by this bug. g_hash_table_replace
behaves like g_hash_table_insert
, but without this problem.
Is there any good reason for using g_hash_table_insert
instead of g_hash_table_replace
? Can you come up with a non-contrived example where you want the behaviour of the former?