PSET5 拼写分割错误

PSET5 Speller Segmentation Fault

// Implements a dictionary's functionality

#include <stdbool.h>
#include <stdio.h>
#include <strings.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "dictionary.h"

#define BASE 256
//No of words in dicionary
unsigned int SIZE = 0;

// Represents a node in a hash table
typedef struct node
{
    char word[LENGTH + 1];
    struct node *next;
}
node;

// Number of buckets in hash table
const unsigned int N = 100800;

// Hash table
node *table[N];

// Returns true if word is in dictionary else false
bool check(const char *word)
{
    node *temp = NULL;
    char new_word[strlen(word) +1];

    strcpy(new_word, word);

    //Lowercase all words from the text to be spellchecked
    for(int i = 0; i < strlen(word); i++)
    {
        new_word[i] = tolower(new_word[i]);
    }

    int n = hash(new_word);

    if( n > N)
        n = n % N;

    temp = table[n];

    if (temp != NULL){
    //Traverse and check word
    while(temp != NULL)
    {
        if(strcasecmp(temp->word, new_word) == 0)
        {
            return true;
        }
        temp = temp->next;
    }

    if (temp->next == NULL && strcasecmp(temp->word, new_word) == 0)
    {
        return true;
    }
    }
    return false;
}

// Hashes word to a number
unsigned int hash(const char *word)
{
    unsigned long h;
    unsigned const char *us;

    /* cast s to unsigned const char * */
    /* this ensures that elements of s will be treated as having values >= 0 */
    us = (unsigned const char *) word;

    h = 0;
    while(*us != '[=10=]')
    {
        h = (h * BASE + *us) % N;
        us++;
    }

    return h;
}

// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
    char w[LENGTH+1];
    FILE *file;
    file = fopen(dictionary, "r");

    if (file == NULL)
    {
        unload();
        return false;
    }

    while(fscanf(file, "%s\n", w) != EOF)
    {
        int n = hash(w);

        if (n > N)
            n = n % N;

        //Incremet in the no of words
        SIZE++;

        //Creating a new node to assign the word
        node *nod = malloc(sizeof(node));
        if(nod == NULL){
            return false;
        }

        strcpy(nod->word, w);

        //Adding the new node to main node
        nod->next = table[n];
        table[n] = nod;

    }
    fclose(file);
    return true;
}

// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
    //No of words from load function
    return SIZE;
}

// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
    //Loopin through the array of linked ist
    for(int i = 0; i < N; i++)
    {
        node *temp = NULL;
        node *cursor = NULL;

        cursor = table[i];

        while(cursor->next != NULL)
        {
            temp = cursor;
            cursor = cursor->next;
            free(temp);
        }
        free(cursor);
    }
    return true;
}

在使用 valgrind 一周后,我能够消除所有的内存泄漏,但随后我得到了这个错误。我的哈希函数现在不是最好的。我正在研究如何实现 murmur 哈希函数。help50 valgrind 并没有真正帮助解决哪一行代码导致段错误。不过我感觉跟指针有关系

她的错误代码

寻求帮助...


/etc/profile.d/cli.sh: line 94:  6280 Segmentation fault      valgrind ./speller texts/cat.txt

Looks like your program is trying to access areas of memory that it isn't supposed to access. Did you try to change a character in a hardcoded string? Are you accessing an element of an array beyond the size of the array? Are you dereferencing a pointer that you haven't initialized? Are you dereferencing a pointer whose value is NULL? Are you dereferencing a pointer after you've freed it?

快一周了。似乎无法弄清楚。

table[i] 未填充时,卸载 while(cursor->next != NULL) 中的这一行会引发段错误。如果该索引中没有单词,则没有 cursor->next.

这样的东西