2009-03-31 10 views
3

私はGLibのハッシュテーブルの実装を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; 
} 

どういうわけか私のテストコードを反復正しくなく、ループの中で、それは常に最後のキーと最後の値のペアを返し、それは常に同じです:私はテストのために次のコードを書きました。ここでの問題は何ですか?上記のコードはそのまま書式で実行されないことがあります。私は何をしようとしているのかを明確にするために一部の部分をコピーして貼り付けました。

答えて

4

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

あなたの挿入コードが壊れていると思います。メモリを1回だけ割り当てていますが、多くの挿入を行い、割り当てられた1つの場所に格納されている値をインクリメントします。

ハッシュテーブルにはポインタが格納されているため、各キーを同じポインタに関連付けることになります。

また、一貫性を保つために、glibでg_malloc()を使用してください。

そして、オブジェクトではなくオブジェクトに対してsizeofを使用することをおすすめします。そういう意味で、あなたはかなり危険な方法で自分を繰り返すことはありません。だから、代わりに

guint32 *a; 

    a = g_malloc(sizeof (guint32)); 

使用

a = g_malloc(sizeof *a); 

あなたは常にで何aポイントを保存するのに十分なスペースを割り当てるように、あなたは後でタイプを変更した場合でも、依存関係を「ロックダウン」この道の。

また、あなたが行うすべてのキャストを詳しく見てください。定数でないポインタをgpointerにキャストすることは、躊躇するプログラマの兆候です。 glibでは、gpointerは、キャストが必要ないようにvoid *の同義語です。それはあなたのコードにうんざりを加えて、読みにくくします。

+0

あなたは速かった:D。 – systemsfault

+1

sizeofの文法(C99 6.5.3)は、 'sizeof unary-expression | sizeof(type-name) 'を使用していますが、この例ではタイプ名のみを使用しているため、ここに括弧が必要です。 –

+0

私は長い間glibを使ってきましたが、このようなものを見つけ出すのに役立ちます。 :) – unwind

関連する問題