0

プログラム内の別の構造体を指すポインタを持つハッシュテーブルを初期化しようとしています。しかし、初期化(H)しようとすると、セグメンテーション違反が発生するようです。メモリの割り当てが間違っている可能性があると思いますが、それがセグメンテーション違反の実際の意味であるかどうかはわかりません。H->hashtable の設定方法は、ハッシュノードの配列である必要があります。ハッシュノード自体は、私の他の構造体へのポインターです。初期化時にのみセグ フォールトが発生するのはなぜですか?

    #include <stdio.h>
    #include <stdlib.h>

    typedef struct Position{
        char data[12];
        struct Hashnode *previous;
        struct Position *next;
        char letter;
        char direction[5];
    } *position;

    typedef struct Hashnode{
       struct Position *INSIDE;
    } *hashnode;

    typedef struct hash_table{
       hashnode *hashtable
    } *HTABLE;


    HTABLE NewHashtable(){
     HTABLE H = (HTABLE) malloc(sizeof(struct hash_table));
     if(H == NULL){ printf("Malloc for new hashtable failed."); exit(1);}
     return H;
    }



    void initialize(HTABLE H){

        H->hashtable = (hashnode*) malloc(100003*sizeof(hashnode));

        int toofer;
        for(toofer = 0; toofer<100003; toofer++){
                 H->hashtable[toofer]->INSIDE = NULL;
                 }
            }

   int main(){
       HTABLE H = NewHashtable();
       initialize(H);

       return 0;
   }
4

3 に答える 3

3

これ:

HTABLE H = (HTABLE) malloc(sizeof(struct hash_table));

ただ恐ろしいです。typedef:ed ポインタ (なぜ人々はまだこれを行うのですか?) を基になる名前と混合し、structそれらが一致することを確認するのは読者の仕事になります。さらに、そのキャストも悪い考えです。

そのはず:

HTABLE H = malloc(sizeof *H);

を維持することを主張する場合typedef

とはいえ、コードinitialize()はおそらくそのmalloc()呼び出しに失敗しており、依存する前にチェックされていません。これは非常に悪い考えです。

さらに、正確に割り当てられているものについて混乱があります。malloc()コードは を割り当てますが100003*sizeof(hashnode)hashnode(再び) :ではなくポインタtypedefとして :edです。次に、ポインターがループ内で逆参照され、混乱を引き起こします。struct

于 2012-12-17T14:54:31.353 に答える
1
    H->hashtable = (hashnode*) malloc(100003*sizeof(hashnode));

    int toofer;
    for(toofer = 0; toofer<100003; toofer++){
             H->hashtable[toofer]->INSIDE = NULL;
             }
        }

最初の行は、に大量のメモリを割り当てますH->hashtable。ランダムなゴミが含まれています。

したがって、ループに入ると、H->hashtable[0]はランダムなガベージになります(すべてH->hashtableがランダムなガベージであるため)。しかし、ループ内でそのランダムなガベージポインタを追跡しようとします。初期化されていないポインタの逆参照は、セグメンテーション違反を取得するための最速の方法です。

これがあなたがそれを見るのを助ける方法です。安全のためにそのメモリをゼロにすることにしたとしましょう。コードは次のようになります。

    H->hashtable = (hashnode*) malloc(100003*sizeof(hashnode));
    memset(H->hashtable, 0, 100003 * sizeof(hashnode));

    int toofer;
    for(toofer = 0; toofer<100003; toofer++){
             H->hashtable[toofer]->INSIDE = NULL;
             }
        }

明らかに、その後はmemset*(H->hashtable)すべてが0に設定されるためH->hashtable、は0H->hashtable[0]になります。0も同様であるためH->hashtable[toofer]->INSIDE、nullポインタを逆参照します。

于 2012-12-17T14:56:58.633 に答える
0
H->hashtable = (hashnode*) malloc(100003*sizeof(hashnode));

より良いはずです

...sizeof(struct Hashnode)...
于 2012-12-17T14:59:21.057 に答える