【问题标题】:CS50 Speller Segmentation FaultCS50 拼写器分段错误
【发布时间】:2020-08-25 20:54:41
【问题描述】:

这就是我运行 help50 valgrind 时得到的结果:

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

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

我不知道自己做错了什么,非常感谢您的帮助。

这是 speller.c 的第 94 行:

 91       // Ignore words with numbers (like MS Word can)
 92       else if (isdigit(c))
 93       {
 94           // Consume remainder of alphanumeric string
 95           while ((c = fgetc(file)) != EOF && isalnum(c));
 96
 97           // Prepare for new word
 98           index = 0;
 99       }

这是我的代码(dictionary.c):

// Implements a dictionary's functionality

#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <strings.h>

#include "dictionary.h"

#define HASHTABLE_SIZE 1985

//word counter
int counter = 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 = 26;

// Hash table
node *table[N];

// Returns true if word is in dictionary else false
bool check(const char *word)
{
    int index = hash(word);


    //Set to the head of the linked list
    node* head = table[index];

    if(head != NULL)
    {
        node* cursor = head;

        while(cursor->next != NULL)
        {
            if(strcasecmp(cursor->word, word) == 0)
            {
                return true;
            }

        cursor = cursor->next;

        }
    }
    return false;
}

//Hash table that I got from https://stackoverflow.com/questions/7666509/hash-function-for-string
// Hashes word to a number
unsigned long hash(const char *str)
{
    unsigned long hash = 5381;
    int c;

    while ((c = *str++))
        hash = ((hash << 5) + hash) + c; /* hash * 33 + c */

    return hash;
}
/*unsigned int hash(const char *word)
{
    // TODO
    return 0;
}*/

// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
    //Open dictionary for read
    FILE *f = fopen(dictionary, "r");

    //Check to see if dictionary is empty
    if(f == NULL)
    {
        printf("Error opening the file.\n");
        return false;
    }

    //array to store words
    char words[LENGTH + 1];

    //Read strings from the file
    while(fscanf(f, "%s", words) != EOF)
    {
        //allocate enough memory to store a new node
        node *n = malloc(sizeof(node));

        //if it doesn't have enough memory to store a node
        if(n == NULL)
        {
            unload();
            return false;
        }

        //copy the word from the array to the node
        strcpy(n->word, words);

        //call hash function
        int index = hash(words) % HASHTABLE_SIZE;

        //insert the node in the hash table

        n->next = table[index];
        table[index] = n;

        counter++;
    }

    //close the file
    fclose(f);
    //success
    return true;
}

// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
    // TODO
    return counter;
}

// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
    for(int i = 0 ; i < HASHTABLE_SIZE ; i ++)
    {
        node* cursor = table[i];
        node* tmp = cursor;

        while(cursor != NULL)
        {
            cursor = cursor->next;
            free(tmp);
            tmp = cursor;
        }

        free(cursor);
    }

    return true;
}

【问题讨论】:

  • 一般来说,我们应该使用 valgrind/address sanitizer 和 gdb 来帮助诊断分段错误。
  • 是的,我想我需要学习如何正确使用 valgrind 才能继续前进。还是谢谢
  • 尝试使用调试器运行它。它会告诉你段错误发生在哪里。

标签: c segmentation-fault cs50


【解决方案1】:

三个明显的问题:

  • table 具有 N (26) 个元素,如此处声明的 node *table[N];
  • load 将在n-&gt;next = table[index]; 基于int index = hash(words) % HASHTABLE_SIZE; 访问尽可能多的HASHTABLE_SIZE (1985) 元素
  • check 将访问多达 ?这里的元素node* head = table[index];(我知道散列函数返回非常大的数字)

【讨论】:

  • 非常感谢,非常感谢您的帮助。这是一个很容易解决的问题,我想我必须先提高我的 valgrind 技能,然后再继续其他内容。
猜你喜欢
  • 2020-08-08
  • 2020-12-20
  • 1970-01-01
  • 1970-01-01
  • 2021-07-31
  • 1970-01-01
  • 1970-01-01
  • 2020-09-22
  • 2020-10-02
相关资源
最近更新 更多