3

ハッシュ テーブル実装 UThash を使用しています。

プリミティブを使用して要素を挿入しています:

    HASH_ADD(hh,hash_table,key,keylen,elem);

そして、プリミティブで要素を取得します:

    HASH_FIND(hh,hash_table,key,keylen,elem);

なんらかの理由で、関数を呼び出すときにハッシュ検索の動作が変更されています。つまり、uthash は table に存在する要素を見つけられません

なんらかの形でメモリが侵害されていると思われます。

この失敗をトリガーする関数は、UThash を失敗させるコードを実行する必要はありません。

    //Note: ct = custom_type
    int func1(ct1 *ptr1, ct2 *ptr2, ct3 *ptr3,char **buffer,size_t *size)
    {
       HASH_FIND(...) //does not work

       /**
        * code
        */
        return 0;
    }

    int func2(ct1 *ptr1,ct2 *ptr2,ct3 *ptr3)
    {
        char *buffer;
        size_t buf_size;

       /**
        * code
        */

        HASH_FIND(...) // works!
        if(func1(ptr1,ptr2,ptr3,&buffer,&buf_size)){
            //code
        }/*error*/

        return 0;
    }

    int func3(ct1 *ptr1,ct2 *ptr2,ct3 *ptr3)
    {
        char *buffer;
        size_t buf_size;

        HASH_FIND(...) // works!
        if(func1(ptr1,ptr2,ptr3,&buffer,&buf_size)){
            //code
        }/*error*/

        /**
         * code
         */

        return 0;
    }

したがって、func2()func3()の両方で同じ動作が発生します。func1()を呼び出した後、 hash_find() が失敗し始めます 。

残りのコードはすべて完全かつ正しく実行されます。

私の明らかな質問は、何がそのようなタイプの失敗を引き起こす可能性があるかということです.

読んでいただきありがとうございます。追加情報があればお気軽にお尋ねください。

4

5 に答える 5

2

これは、同じキーを持つ複数のアイテムをハッシュに追加することによって発生する可能性があります。uthashを使用する場合は、構造内に重複したキーがないことを確認するか、古いアイテムを新しいアイテムに置き換えるラッパー関数を提供する必要があります。そうしないと、構造の動作が予測できず、説明した障害が発生する可能性があります。

uthashユーザーガイドから:

プログラムによって重複キーが生成される可能性がある場合は、キーをハッシュに追加する前に、一意性を明示的に確認する必要があります。キーがすでにハッシュに含まれている場合は、アイテムを追加するのではなく、ハッシュ内の既存の構造を変更するだけで済みます。同じキーを持つ2つのアイテムをハッシュテーブルに追加するとエラーになります。

于 2012-12-29T16:43:15.680 に答える
0

キーのタイプがunsigned charの場合、 int HASH_FIND_INTに置き換えた後、同様の問題が発生し、適切に機能し始めました。さらに調査すると、気になるsigned charunsigned charは適切ではありませんが、short intunsigned short intも問題なく機能するようです。

ハッシュ関数の計算アルゴリズムが正しく動作するには、おそらく 8 ビットでは不十分です。unsigned char操作を使用する元のコードは断続的であり、一部のビルドではコードが機能し、他のビルドでは機能しなかったことに注意してください (変更は uthash とは関係ありません)。

結論: HASH_FIND_INT を適切に操作するには、signed int型のキーを使用するか、自己責任でshort intまたはunsigned shortを使用してください。

于 2016-02-03T09:24:40.627 に答える
0

これは、データではなくポインターをハッシュしているためです。

HASH_ADD_KEYPTRを使用します。

于 2015-03-17T15:10:29.667 に答える
0

struct@yerdenで言及されているように、パディングのためにこの問題にも遭遇しました。structgcc では、次のように pack 属性を使用して を定義するのは簡単ですが、時間がかかります。

struct __attribute__((__packed__)) a_struct {
    char a, b;
    unsigned int i;
};

この問題は、構造キーのuthash マニュアルstructで言及されており、解決策は、そこに示されているように、ハッシュに追加する前にをゼロにすることです。

別の解決策は、構造体のパッキングについて学びstruct、パディングが問題にならないように再編成することです。構造体のパッキングの簡単な概要は、別の役に立つスタック オーバーフローの質問に記載されています。

于 2019-03-23T15:10:57.083 に答える