2010-04-19 59 views
2

我試圖構建一個包含ints,time_t和幾個char *的struct的實例的GHashTable。插入非pod結構到GHashTable中

我的問題是,你如何將一個結構的實例插入GHashTable?有很多關於如何插入字符串或int的例子(分別使用g_str_hash和g_int_hash),但我猜想我想使用g_direct_hash,而且我似乎無法找到任何示例。

理想的情況下,我的代碼是這樣的:

GHashtable table; 
table = g_hash_table_new(g_direct_hash, g_direct_equal); 
struct mystruct; 
mystruct.a = 1; 
mystruct.b = "hello"; 
mystruct.c = 5; 
mystruct.d = "test"; 

g_hash_table_insert(table,mystruct.a,mystruct); 

顯然,這是不正確的,它不會編譯。任何人都可以提供一個可以做我想做的事情的例子嗎? 謝謝, 裏克

回答

1

你必須在堆上分配的結構,以便您可以存儲在哈希表的指針:

struct SomeType * p = malloc(sizeof(struct SomeType)); 
p->a = 1; 
//etc.. 
g_hash_table_insert(table,p->a,p); 

您還需要使用g_hash_table_new_full(),這樣就可以正常在表被銷燬時釋放指針。

2

您不能插入自動變量;您必須爲數據分配內存以動態方式存儲,即使用g_malloc()或等效內容。

然後,您需要找出一種方法來根據您的數據計算散列值,以幫助該表高效。在這裏使用g_direct_hash()不太好;它將使用指向數據的指針作爲散列值。

看起來好像你想用你的結構的成員a作爲關鍵;這個字段是什麼類型?如果它是整數,則可以使用g_int_hash()

我認爲這是一起的實際代碼應該是什麼樣子的線路更多:

GHashtable *table; 
struct mystruct *my; 

table = g_hash_table_new_full(g_int_hash, g_int_equal, NULL, g_free); 
my = g_malloc(sizeof *my); 
my->a = 1; 
my->b = "hello"; 
my->c = 5; 
my->d = "test"; 

g_hash_table_insert(table, GINT_TO_POINTER(my->a), my); 

注意,這個假設bd成員只是字符指針,因爲沒有存儲動態分配字符串。

+0

'表= g_hash_table_new_full(g_int_hash,g_int_equal,NULL,g_free);' – ntd 2010-04-20 20:05:46

+0

@ntd:謝謝,固定! – unwind 2010-04-21 06:43:33

+0

一個改進是使用g_new(struct mystruct,1)而不是g_malloc。刪除兩個錯誤來源(分配錯誤的大小,並將內存分配給錯誤的類型)。 – 2010-11-01 14:17:07

1

謝謝。上面的例子有所幫助。在閱讀這些代碼並在網上查看代碼示例後,我可以使其工作。以下是我寫的一個樣本工作代碼:

 

#include <stdio.h> 
#include <glib.h> 
#include <stdlib.h> 

struct struct_process { 
    int pid; 
    char* file_to_process; 
}; 

typedef struct struct_process Process; 

int main() { 
    GHashTable* hash_table = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free); 

    Process* p1 = (Process*)(malloc(sizeof(Process))); 
    p1->pid = 1234; 
    p1->file_to_process= "/var/tmp/p1"; 

    g_hash_table_insert(hash_table, GINT_TO_POINTER(p1->pid), GINT_TO_POINTER(p1)); 

    # replace 1234 by some other key to see that it returns NULL on nonexistent keys 
    Process* p3 = (Process*)(g_hash_table_lookup(hash_table, GINT_TO_POINTER(1234))); 

    if (p3 == NULL) { 
     printf("could not find\n"); 
    } else { 
     printf("found and i have to process %s\n", p3->file_to_process); 
    } 
    g_hash_table_destroy(hash_table); 
} 
`