使用int作为g_hash_table中的键

问题描述:

我在C中有一些代码,我想用int作为键和gnome散列表中的值。但如果我写:使用int作为g_hash_table中的键

GHashTable* table = g_hash_table_new(g_direct_hash, g_direct_equal); 
int tmp = 0; 
int value = 255; 
g_hash_table_insert(table, (gpointer)tmp, (gpointer) 255); 

我得到了一些关于从不同大小的整数投射指针和应用程序返回分段错误的警告。我知道这可以通过指针来完成,但我想知道是否有直接使用int来优化过程的方法。我也打开尝试新的解决方案(始终在C与侏儒散列表),表现更好。我只需创建一个哈希表并用相同的值填充一定数量的键,然后在后一阶段与其中的值进行比较,最后使用固定值对其中的每个值进行比较。

+0

这听起来像你有一个64位平台:在这种情况下,sizeof(int)可能不等于sizeof(void *)。然而,在这种情况下,答案解决了这个问题。 – Scheff

你有两个选择:

  • 使用g_direct_hash()G_INT_TO_POINTER()键;或
  • 使用g_int_hash()指针指向您的整数键。

所以在第一种情况下,这将是:

int tmp = 0; 
int value = 255; 

GHashTable *table = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL); 
g_hash_table_insert (table, GINT_TO_POINTER (tmp), GINT_TO_POINTER (value)); 

在第二,它是:

int tmp = 0; 
int value = 255; 

GHashTable *table = g_hash_table_new_full (g_int_hash, g_int_equal, NULL, NULL); 
g_hash_table_insert(table, &tmp, GINT_TO_POINTER (value)); 

虽然你必须保证的关键指向&tmp不而它的入口在哈希表中 - 所以这只适用于分配的密钥,如下所示:

int tmp = 0; 
int *key = g_new0 (gint, 1); 
*key = tmp; 
int value = 255; 

GHashTable *table = g_hash_table_new_full (g_int_hash, g_int_equal, g_free, NULL); 
g_hash_table_insert(table, key, GINT_TO_POINTER (value)); 

因此,例如,如果您希望基于现有堆分配结构中的整数字段的值来键入散列表,则该第二个选项更有意义,该结构将存储为散列表项中的值(所以你不需要额外的分配只是为了关键)。

请注意,在这两种情况下,您都要使用GINT_TO_POINTER()作为要存储的值,因为值始终被视为指针,并且与您正在使用的散列函数和相等函数无关。

还要注意,使用g_hash_table_new_full()并通过NULL作为最后的两个参数(除了第三个例子),使得它更清楚地表明,哈希表没有取得您通过它的键和值的所有权。 (最后的两个参数给出了键和值的自由函数。)

+0

太棒了,这个答案更加完整,我最终使用了直接哈希。非常感谢! – gabrielesani

你应该使用GINT_TO_POINTER宏:

g_hash_table_insert(table, GINT_TO_POINTER(tmp), GINT_TO_POINTER(255)); 

,将允许获得来自warning: cast to pointer from integer of different size警告摆脱。

+0

这有效地消除了警告,但我仍然遇到分段错误。 – gabrielesani

+1

也使用'g_int_equal()'和'g_int_hash()'。 – TingPing

+0

这样做,谢谢! – gabrielesani