2009-03-31 7 views
3

Ich werde 's Hash - Tabelle Implementierung in einem C - Programm und nur für jetzt Ich experimentiere nur damit. Ich habe das folgende Stück Code zum Testen:GLib Hash Tabelle Schleife Problem

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

Irgendwie Iterierten richtig meines Testcode, sondern in der Schleife gibt es immer noch die letzten Schlüssel und letzten Wert-Paare, und es ist immer das gleiche. Was ist das Problem hier? Der obige Code wird möglicherweise nicht mit seinem Format ausgeführt. Ich habe einige Teile kopiert und eingefügt, um eine klare Vorstellung davon zu geben, was ich zu tun versuche.

Antwort

4

Es liegt ein Fehler in key, a Deklarationen vor. Sie setzen immer den gleichen Zeiger in die Hash-Tabelle. Versuchen Sie:

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

Ich denke, dass Ihre Einfüge-Code ist gebrochen. Sie weisen Speicher nur einmal zu, führen dann aber viele Einfügungen durch und erhöhen den Wert, der an der einzelnen zugewiesenen Speicherposition gespeichert ist.

In der Hash-Tabelle wird der Zeiger gespeichert, sodass jeder Schlüssel mit demselben Zeiger verknüpft wird.

Auch sollten Sie wahrscheinlich g_malloc() mit glib aus Konsistenzgründen verwenden.

Und ich empfehle immer sizeof auf Objekte und nicht auf ihre Arten zu verwenden; Auf diese Weise wiederholst du dich nicht auf eine ebenso gefährliche Art und Weise. Anstatt also

guint32 *a; 

    a = g_malloc(sizeof (guint32)); 

Verwendung

a = g_malloc(sizeof *a); 

Auf diese Weise können „sperren“ die Abhängigkeit, so dass Sie immer genug Platz zuweisen zu speichern, was a Punkte an, auch wenn Sie später die Art ändern .

Weiterhin sollten Sie sich jeden Wurf, den Sie machen, genau ansehen. Das Übertragen eines nicht konstanten Zeigers auf gpointer ist ein Zeichen für einen zögerlichen Programmierer. Mit Glib ist gpointer nur ein Synonym für void *, so dass Cast nie benötigt wird. Es fügt Ihrem Code nur noch mehr hinzu und erschwert das Lesen.

+0

Danke, Sie waren schnell: D. – systemsfault

+1

Die Grammatik für sizeof (C99 6.5.3) ist 'sizeof unary-expression | sizeof (type-name) ', und die einzige Verwendung in dem Beispiel ist mit einem Typnamen, so dass die Parens hier erforderlich sind. –

+0

Ich habe Glib für eine lange Zeit verwendet, es hilft bei der Suche nach solchen Sachen. :) – unwind