2012-09-26 48 views
0

我添加了幾個鍵值對到我的GLib哈希表,這是我的內存結構。關鍵是從malloc返回的(char *)指針。該值是分配的malloc的大小。GLib哈希表沒有返回正確的值

void addstomemstruct(struct memory *mem, char *key_address, size_t sz) { 
    g_hash_table_insert(mem->singleton, key_address, &sz); 
    printf("** retrieving size: %Zu add=%p\n",(*(size_t*) g_hash_table_lookup(mem->singleton, key_address)), key_address); 
} 

後來,我去的時候根據基於密鑰的值來檢索值,返回的大小(值)始終是10,這是我加入到哈希表中的最後一個值

size_t get_blocksize(GHashTable *hashtable, char *key_address, size_t *result_flag) 
{ size_t *sz_ptr = (size_t *) g_hash_table_lookup(hashtable, key_address); 
    ... 

char *logmsg;asprintf(&logmsg,"In get_blocksize: *sz_ptr=%Zu\n",*sz_ptr); 
    log_msg(logmsg); 

printf("** retrieving size: %Zu add=%p\n",(*(size_t*) g_hash_table_lookup(hashtable, key_address)), key_address); 
... 
} 

打印輸出:

preparing to add pointer: 0x9b52f10 
** adding size: 1 
** retrieving size: 1 add=0x9b52f10 
preparing to add pointer: 0x9b52f48 
** adding size: 2 
** retrieving size: 2 add=0x9b52f48 
preparing to add pointer: 0x9b52f58 
** adding size: 3 
... 
preparing to add pointer: 0x9b52fc8 
** adding size: 10 
** retrieving size: 10 add=0x9b52fc8 

再後來,當我嘗試檢索的第一個值:

In get_blocksize: *sz_ptr=10 
** retrieving size: 10 add=0x9b52f10 
Freed address 0x9b52f10. Size: 10. mem->stats->active_count=9, mem->stats->active_size=45. 

回答

3

您正在傳遞一個指向自動存儲持續時間變量(函數參數)的指針作爲散列表值。當它超出範圍時,訪問它是一種未定義的行爲。

您可以:

  • 分配存儲爲szmalloc/gnew和哈希表創建註冊一個適當的value_destroy_func
  • 利用size_t值適合指針並將其轉換爲gpointer。技術上這是一個UB,但應該在大多數平臺上工作。除非將小物件分配確定爲瓶頸,否則可能不應該這樣做。
+0

謝謝。 UB是什麼意思?第二個選項是否允許我不必分配空間?哈希表存在於調用get_blocksize的函數範圍之外。 – user994165

+0

UB =未定義的行爲。是的,你將價值投入到商店的指針並在檢索時返回。只是不要將它用作指針(GLib不在內部)。 – rkhayrov

+1

您可以使用宏「GSIZE_TO_POINTER」和「GPOINTER_TO_SIZE」以獨立於平臺的方式完成該轉換。 – ptomato