3

私は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

2 に答える 2

9

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

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

また、一貫性を保つために、おそらくg_malloc()glibと一緒に使用する必要があります。

sizeofまた、タイプではなくオブジェクトで使用することを常にお勧めします。そうすれば、危険な方法で自分自身を繰り返すことはありません。だから、代わりに

  guint32 *a;

  a = g_malloc(sizeof (guint32));

使用する

  a = g_malloc(sizeof *a);

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

さらに、あなたはあなたがするすべてのキャストをよく見るべきです。定数でないポインタをにキャストするgpointerことは、ためらいのあるプログラマーの兆候です。glibでは、はのgpointer同義語でvoid *あるため、キャストは必要ありません。コードに雑然としたものが追加されるだけで、読みにくくなります。

于 2009-03-31T08:05:03.730 に答える
4

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;
}
于 2009-10-21T12:14:25.083 に答える