【问题标题】:GLib: Hashtable not finding values correctlyGLib:哈希表未正确找到值
【发布时间】:2017-06-29 18:48:09
【问题描述】:

所以我最近一直在使用GLib的类型,比如lists和maps,但是遇到了一个比较麻烦的问题。

开始,我创建了我的哈希表:

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);

注意:我是动态分配指针的,那是因为我尝试只传递静态数组但它不起作用(结果两者都不起作用)

然后我继续尝试稍后检索这些 uint:

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.

感谢您的阅读...

【问题讨论】:

  • 请分享您的 map_insertmap_find 代码,因为我假设它们都是围绕 GLib 哈希表函数的包装函数。

标签: c string hashtable glib assimp


【解决方案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);
}

至于为什么它适用于静态字符串文字,我会说它是编译器优化二进制空间并将两个内容相同的文字折叠到单个 DATA 段记录中,因此它散列相同的指针,这就是它看起来有效的原因正确,虽然它没有。

【讨论】:

  • 但我不是在散列字符串,我正在尝试将 uint 映射到字符串。基本上,字符串作为键,单位作为值
  • @Whiteclaws Hashtable(像一个通用数据结构)的工作方式如下。在大多数情况下,哈希键是某个范围内的整数值,而这个范围通常是哈希表的桶数。因此,当键查找发生时,计算被查找键的第一个哈希,之后我们需要找到一个存储桶并将存储的键与查找键进行比较(因为有多个键产生相同的哈希)。这就是为什么 hashtable 构造函数同时具有 hash 和 compare 函数的原因。这就是为什么他们两个都需要知道如何使用零终止字符串。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多