我使用malloc'd字符串作为GLib哈希表的键。然后,我有几个更新。每次更新都使用一个新的malloced字符串,该字符串在实际的字符序列中是相同的。如果我执行插入操作,是否会覆盖旧字符串?我如何确保释放它,以便我不保留额外的副本?如果它没有被覆盖,我怎样才能确保实现更新而不会太慢?
答案 0 :(得分:5)
如果在创建哈希表时向g_hash_table_new_full
提供正确的比较器和键/值析构函数,则不必执行任何额外的操作。该表将理解即使密钥字符串是单独的副本,它们也是相同的,并且它也会自动释放相同密钥的重复副本。
这是一个例子(丑陋的printf
仅用于显示发生的事情):
首先编写一个析构函数:
void
free_data (gpointer data)
{
printf ("freeing: %s %p\n", (char *) data, data);
free (data);
}
然后你实例化并使用GHashTable
:
int main (void)
{
char *key, *val;
GHashTable *hash_table
= g_hash_table_new_full (g_str_hash, /* Hash function */
g_str_equal, /* Comparator */
free_data, /* Key destructor */
free_data); /* Val destructor */
/* Insert 'k_1' */
key = strdup ("k_1");
printf ("%s %p\n", key, key);
val = strdup ("v_1");
printf ("%s %p\n", val, val);
printf ("inserting\n");
g_hash_table_insert (hash_table, key, val);
printf ("insert finished\n");
/* Insert 'k_1' again using new strings */
key = strdup ("k_1");
printf ("%s %p\n", key, key);
val = strdup ("new_v_1");
printf ("%s %p\n", val, val);
printf ("inserting\n");
g_hash_table_insert (hash_table, key, val);
printf ("insert finished\n");
g_hash_table_unref (hash_table);
return 0;
}
这是测试运行的样子:
k_1 0x80cce70
v_1 0x80cce80
inserting
insert finished
k_1 0x80cce90
new_v_1 0x80ccea0
inserting
freeing: k_1 0x80cce90
freeing: v_1 0x80cce80
insert finished
freeing: k_1 0x80cce70
freeing: new_v_1 0x80ccea0
您将看到,如果您创建与现有密钥相同的“新”密钥,并尝试插入相应的“新”值,则“插入”操作会自动销毁“新”密钥(因为它是与现有的相同),以及旧值(因为它必须替换为新值)。
答案 1 :(得分:1)
使用g_hash_table_insert ()
时,只有在使用g_hash_table_new_full
创建哈希表时提供key_destroy_func
时才会释放键值。如果您使用g_hash_table_new
创建了哈希表,则必须在插入后释放密钥。