1

我使用 malloc 的字符串作为 GLib 哈希表的键。然后我有几个更新要做。每次更新都使用一个新分配的字符串,该字符串在实际字符序列中是相同的。如果我进行插入,旧字符串会被覆盖吗?我怎样才能确保释放它,这样我就不会保留多余的副本?如果它没有被覆盖,我怎样才能确保实现更新而不会太慢?

4

2 回答 2

5

如果您在创建哈希表时提供了正确的比较器和键/值析构函数g_hash_table_new_full,则无需做任何额外的事情。该表将理解密钥字符串是相同的,即使它们是单独的副本,它也会自动释放相同密钥的重复副本。

这是一个示例(丑陋printf的 s 仅用于显示正在发生的事情):

首先你写一个析构函数

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

您会看到,如果您创建一个与现有密钥相同的“新”密钥,并尝试插入相应的“新”值,那么“插入”操作会自动销毁“新”密钥(因为它现有的),以及旧值(因为必须用新值替换它)。

于 2012-10-03T20:30:10.117 回答
1

使用,仅当您在使用 创建哈希表时g_hash_table_insert ()提供了 a 时,才释放键值。如果您使用创建哈希表,则必须在插入后释放您的密钥(如有必要)。key_destroy_funcg_hash_table_new_fullg_hash_table_new

于 2012-10-03T20:30:42.987 回答