2

この関数「ロード」を使用して、辞書から単語を読み取り、それらをリンクされたリストのハッシュテーブルに入れます。行を読み取って new_node->text に保存しようとすると、コンパイラが SEGMENTATION FAULT を返しますが、その理由がわかりません。strncpy を使用するとエラーが表示されます。

#define HASHTABLE_SIZE 76801


typedef struct node
{
        char text[LENGTH+1];
        //char* text;
        //link to the next word
        struct node* next_word;
}
node;


    node* hashtable[HASHTABLE_SIZE];

    bool load(const char* dictionary)
    {
        FILE* file = fopen(dictionary,"r");
        unsigned long index = 0;
        char str[LENGTH+1];

        if(file == NULL)
        {
            printf("Error opening file!");
            return false;
        }

        while(! feof(file))
        {
            node * new_node = malloc(sizeof(node)+1000);


            while( fscanf(file,"%s",str) > 0)
            {
                printf("The word is %s",str);
                strncpy(new_node->text,str,LENGTH+1);
                //strcpy(new_node->text,str);

                new_node->next_word = NULL;
                index = hash( (unsigned char*)new_node->text);

                if(hashtable[index] == NULL)
                {
                    hashtable[index] = new_node;
                }
                else
                {
                    new_node->next_word =  hashtable[index];
                    hashtable[index] = new_node;
                }

                n_words++;

            }
            //free(new_node);



        }
        fclose(file);
        loaded = true;

        return true;    
    }
4

1 に答える 1

5

コードを 1 行ずつ見ていきましょう。

    while(! feof(file))
    {

これは正しい使い方ではありませんfeof-なぜ「while ( !feof (file) )」は常に間違っているのか? ここStackOverflowにあります。

        node * new_node = malloc(sizeof(node)+1000);

うーん、わかりました。1 つのノードと 1000 バイトにスペースを割り当てます。それは少し奇妙ですが、ねえ... RAMは安いです。

        while( fscanf(file,"%s",str) > 0)
        {

うーん...別のループ?わかった...

            printf("The word is %s",str);
            strncpy(new_node->text,str,LENGTH+1);
            //strcpy(new_node->text,str);

            new_node->next_word = NULL;
            index = hash( (unsigned char*)new_node->text);

おい!ちょっと待ってください... この 2 番目のループでは、new_node繰り返し上書きを続けています...

            if(hashtable[index] == NULL)
            {
                hashtable[index] = new_node;
            }
            else
            {
                new_node->next_word =  hashtable[index];
                hashtable[index] = new_node;
            }

両方の単語が同じバケットにハッシュされると仮定します。

OK、最初のループでhashtable[index]は を指し、 を指すNULLように設定されnew_nodeます。

ループの 2 回目では、 (ヒント: ) を指すものは何でも指すように作成され、 ) を指すように作成されるわけでhashtable[index]はありません。NULLnew_nodehashtable[index]new_nodehashtable[index]new_node

ウロボロスって知ってる?

同じバケットにハッシュしないと仮定します。

バケットの 1 つに間違った情報が含まれています。最初にバケット 1 に "hello" を追加し、最初にバケット 2 に "さようなら" を追加すると、バケット 1 をトラバースしようとすると (リンク コードが壊れているためだけに) バケット 1 に属さない "さようなら" を見つけることができます。全て。

追加する単語ごとに新しいノードを割り当てる必要があります。同じノードを再利用しないでください。

于 2013-02-28T18:30:45.730 に答える