2017-06-29 72 views
0

所以我最近使用GLib的类型,如列表和地图,但我遇到了一个相当麻烦的问题。GLib:哈希表没有正确找到值

出发,我创建了哈希表,例如:

BoneIdMap = g_hash_table_new(g_direct_hash, g_str_equal); 

我再尝试一下,在一个字符串键插入一些uint和它完美的作品:

char* string = alloq_calloc(&model->dynamic, strlen(aimesh->mBones[x]->mName.data) + 1, sizeof(char)); 
strcpy(string, aimesh->mBones[x]->mName. 
if(map_find(&model->BoneIdMap, string, &handle)) { 
    index = *handle; 
} else { 
    index = model->BoneIdMap.size; 
} 
map_insert(&model->BoneIdMap, &index, sizeof(uint), string); 

请注意:我动态地分配指针,这是因为我试图传递静态数组,它不起作用(原来两者都不起作用)

然后我继续尝试并检索那些提示WN行:

char* string = alloq_calloc(&model->dynamic, strlen(ainode->mName.data) + 1, sizeof(char)); 
strcpy(string, ainode->mName.data); 
/* Time to do some debugging */ 
if(map_find(&model->BoneIdMap, string, &handle)) { 

但它根本没有工作...我试着检索所有键到一个数组:

uint len; 
char** arr = g_hash_table_get_keys_as_array(model->BoneIdMap.table, &len); 
for(int i = 0; i < len; ++i) { 
    if(arr[i]) printf("Key: %s\n", arr[i]); 
     if(!strcmp(arr[i], ainode->mName.data)) printf("Yes!\n"); 
} 
printf("----------------------------\n"); 

和它的作品! (???)

Key: pelvis 
Key: toe.L 
Yes! 
Key: sheath 
Key: lamp 
---------------------------- 
Key: toe.R 
Key: shin.L 
Key: fingerstip.R 
Key: neck 
Key: thigh.R 
Key: fingers.L 
Key: shin.R 
Key: spine 
Key: lamp 
Key: head 
Key: fingerstip.L 
Key: thm_end.L 
Key: thm_end.R 
Key: tiptoe.L 
Yes! 
Key: upperarm.R 

注意到,如果我是使用静态字符串添加一个关键就在那里除了上述的打印功能,并试图找到它,它的工作! 这让我很困惑...

顺便说一句,MNAME是aiString(ASSIMP) -

Public Attributes 
char data [MAXLEN] 
    String buffer. 
size_t length 
    Binary length of the string excluding the terminal 0. 

感谢您阅读...

+0

请分享您的'map_insert'和'map_find'代码,因为我假设它们都是GLib散列表函数的包装函数。 – tgregory

回答

1

您正在使用g_direct_hash哈希函数这意味着要用于字符串键的gpointer,请尝试将其更改为g_str_hash

// g_direct_hash implementation seems to be this 
guint 
g_direct_hash (gconstpointer v) 
{ 
    return GPOINTER_TO_UINT (v); 
} 

至于为什么它与静态字符串字面工作,我会说这是编译器优化的二进制空间和折叠两个字符串具有相同内容合并到一个数据段的记录,因此它哈希相同的指针是为什么它看起来像正常工作,虽然它没有。

+0

但我没有散列字符串,我试图将字符映射到字符串。基本上,字符串作为键,以及值作为值 – Whiteclaws

+0

@Whiteclaws Hashtable(如通用数据结构)的工作原理如下。在大多数情况下,散列键是散列键,在某些范围内,散列键是一个整数值,这个范围通常是散列表的桶数。因此,当密钥查找发生时,首先计算被查找密钥的散列值,然后我们需要查找一个存储桶并将存储密钥与查找密钥进行比较(因为存在多个密钥生成相同的散列值)。这就是为什么散列表构造函数具有散列函数和比较函数的原因。这就是为什么他们都需要知道如何使用零终止的字符串。 – tgregory