2017-06-29 88 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