【问题标题】:GLib Hash Table Loop ProblemGLib 哈希表循环问题
【发布时间】:2009-03-31 07:59:07
【问题描述】:

我将在 C 程序中使用 GLib 的哈希表实现,现在只是 我只是在试验它。我编写了以下代码进行测试:

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

 int main(){
 // Some codes and declerations here
 GHashTable *g_hash_table;
 uint32_t *a;
 a=(uint32_t *)malloc(sizeof(uint32_t));
 if(a==NULL){
    printf("Not Enough Mem For a\n");
    return 1;
 }
 *a=1123231;

 uint32_t* key;
 key=(uint32_t *)malloc(sizeof(uint32_t));
 if(key==NULL){
     printf("Not Enough Mem For key\n");
     return 1;
 }
 *key=122312312;
 int i;
 g_hash_table=g_hash_table_new(g_int_hash, g_int_equal);
 for(i=0;i<TABLE_SIZE;i++){
     *key+=1;
     *a+=1;
     g_hash_table_insert(g_hash_table,(gpointer)key,(gpointer)a);
     uint32_t *x=(uint32_t *)g_hash_table_lookup(g_hash_table,key);
     printf("Counter:%d,  %u\n",i,*x);
 }

GHashTableIter iter;
g_hash_table_iter_init(&iter,g_hash_table);
int size=g_hash_table_size(g_hash_table);
printf("First size: %d\n",size);
uint32_t *val;
uint32_t *key_;
int counter=0;

// My problem is in the following loop it 
// always returns the same and the last key value pair
 while(g_hash_table_iter_next(&iter,(gpointer*)(void*)&key_,(gpointer*)(void*)&val)){
     counter++;
     printf("%u %u\n",(uint32_t)*key_,(uint32_t)*val);
     printf("Counter: %d\n",counter);
 }
 //Some more code here        
    return 0;
}

不知何故,我的测试代码可以正确迭代,但在循环中它总是返回最后一个键和最后一个值对,而且它总是相同的。这里有什么问题?上面的代码可能无法运行,因为它是格式。我只是复制并粘贴了一些部分,以便清楚地了解我要做什么。

【问题讨论】:

    标签: c hashtable glib


    【解决方案1】:

    我认为您的插入代码已损坏。您只分配一次内存,然后进行多次插入,增加存储在每个之间的单个分配位置中的值。

    哈希表存储您的指针,因此最终会将每个键与相同的指针相关联。

    此外,您可能应该将g_malloc() 与 glib 一起使用,以保持一致性。

    而且我总是建议在对象而不是它们的类型上使用sizeof;这样你就不会以非常危险的方式重复自己。所以,而不是

      guint32 *a;
    
      a = g_malloc(sizeof (guint32));
    

    使用

      a = g_malloc(sizeof *a);
    

    这样你“锁定”了依赖,这样你总是分配足够的空间来存储a指向的任何东西,即使你以后改变了类型。

    此外,您应该仔细检查您所做的每个演员表。将任何非常量指针转换为gpointer 是程序员犹豫不决的标志。使用 glib,gpointer 只是 void * 的同义词,因此永远不需要强制转换。它只会给您的代码添加杂乱无章的内容,使其更难阅读。

    【讨论】:

    • sizeof (C99 6.5.3) 的语法是` sizeof unary-expression | sizeof ( type-name ) ` ,示例中唯一使用的是类型名称,因此此处需要括号。
    • 我已经使用 glib 很长时间了,它有助于发现这样的东西。 :)
    • @Pete:是的,我会改写我的反对意见。
    【解决方案2】:

    keya 声明中有错误。您总是将相同的指针放在哈希表中。试试:

    #include <glib.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include <stdio.h>
    #include <string.h>
    
    #define TABLE_SIZE 12
    
    int main() {
        // Some codes and declarations here
        GHashTable *g_hash_table;
        int i;
    
        g_hash_table = g_hash_table_new(g_int_hash, g_int_equal);
        for (i=0; i<TABLE_SIZE; i++)
        {
            uint32_t* key = (uint32_t *)malloc(sizeof(uint32_t));
            uint32_t* a = (uint32_t *)malloc(sizeof(uint32_t));
            *key = i;
            *a   = i+10;
            g_hash_table_insert(g_hash_table, (gpointer)key, (gpointer)a);
            uint32_t *x = (uint32_t *)g_hash_table_lookup(g_hash_table,key);
            printf("key: %d -->  %u\n", *key ,*x);
        }
    
        GHashTableIter iter;
        int size=g_hash_table_size(g_hash_table);
        printf("First size: %d\n", size);
    
        uint32_t *val;
        uint32_t *key_;
    
        // My problem is in the following loop
        // it always returns the same and the last key value pair
    
        g_hash_table_iter_init (&iter, g_hash_table);
        while (g_hash_table_iter_next (&iter, (gpointer) &key_, (gpointer) &val))
        {
            printf("key %u ---> %u\n", (uint32_t)*key_, (uint32_t)*val);
        }
    
        // TODO: free keys
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多