PSET5桨叶分段故障

时间:2020-06-29 11:50:33

标签: c cs50

// 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 != '\0')
    {
        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一周后,我可以摆脱所有内存泄漏,但是随后出现此错误。我的哈希函数现在不是最好的。我正在研究如何实现杂项哈希功能。help50valgrind并不能真正帮助导致段错误的代码行。但是我觉得它与指针有关。

显示错误代码

寻求帮助...


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

看起来您的程序正在尝试访问不应访问的内存区域。您是否尝试过更改硬编码字符串中的字符?您是否正在访问超出数组大小的数组元素?您是否在取消引用尚未初始化的指针?您是否正在取消引用值为NULL的指针?释放指针后要取消引用吗?

已经快一个星期了。似乎无法弄清楚。

1 个答案:

答案 0 :(得分:0)

当未填充for i in [0, vecDup.size()[ if vecDup[i] matches the predicate add i to set of results 时,此行卸载while(cursor->next != NULL)会引发段错误。如果该索引中没有单词,则没有table[i]这样的东西。