Проблема петли хеш-таблицы GLib - PullRequest
3 голосов
/ 31 марта 2009

Я собираюсь использовать реализацию хеш-таблицы GLib в программе на C и сейчас Я просто экспериментирую с этим. Я написал следующий фрагмент кода для тестирования:

 #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;
}

Каким-то образом мой тестовый код повторяется правильно, но в цикле он всегда возвращает пары последнего ключа и последнего значения, и он всегда одинаков. В чем здесь проблема? Приведенный выше код может не работать с его форматом. Я просто скопировал и вставил некоторые части, чтобы дать четкое представление о том, что я пытаюсь сделать.

Ответы [ 2 ]

9 голосов
/ 31 марта 2009

Я думаю, ваш код вставки не работает. Вы выделяете память только один раз, но затем выполняете много операций вставки, увеличивая значение, хранящееся в одном выделенном месте между каждым.

Хеш-таблица хранит ваш указатель, поэтому в конечном итоге все ключи будут ассоциироваться с одним и тем же указателем.

Кроме того, вам, вероятно, следует использовать g_malloc() с glib для согласованности.

И я всегда рекомендую использовать sizeof для объектов, а не для их типов; таким образом, вы не повторяете себя так опасно. Итак, вместо

  guint32 *a;

  a = g_malloc(sizeof (guint32));

использование

  a = g_malloc(sizeof *a);

Таким образом, вы «блокируете» зависимость, так что вы всегда выделяете достаточно места для хранения того, на что указывает a, даже если вы позже измените тип.

Кроме того, вы должны внимательно смотреть на каждый актерский состав, который вы делаете. Приведение любого неконстантного указателя к gpointer является признаком нерешительного программиста. С glib gpointer является просто синонимом void *, поэтому приведение никогда не требуется. Это просто добавляет в ваш код неприятности, затрудняя чтение.

4 голосов
/ 21 октября 2009

Ошибка в объявлениях key, a. Вы всегда помещаете один и тот же указатель в хеш-таблицу. Попробуйте:

#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;
}
...