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

让我们逐行查看您的代码,好吗?

    while(! feof(file))
    {

这不是正确的使用方式feof——查看帖子为什么“while (!feof (file))”总是错误的?就在 StackOverflow 上。

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

嗯。。好。我们为一个节点和 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);

嘿!等一下……在第二个循环中,我们不断new_node重复覆盖……

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

假设两个词散列到同一个桶:

好的,所以第一次通过循环,hashtable[index]将指向NULL并设置为指向new_node

第二次通过循环,hashtable[index]is not NULLsonew_node将指向任何hashtable[index]指向 (hint: new_node) 并将hashtable[index]指向new_node)。

你知道衔尾蛇是什么吗?

现在假设它们不散列到同一个桶:

现在其中一个桶包含错误的信息。如果您首先在存储桶 1 中添加“hello”,然后在存储桶 2 中添加“再见”,当您尝试遍历存储桶 1 时,您可能(仅因为链接代码被破坏)找到不属于存储桶 1 的“再见”全部。

您应该为要添加的每个单词分配一个节点。不要重复使用同一个节点。

于 2013-02-28T18:30:45.730 回答