Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
尝试将字典加载到内存时C中出现分段错误(cs50 pset5,拼写器)_C_Memory_Segmentation Fault_Cs50 - Fatal编程技术网

尝试将字典加载到内存时C中出现分段错误(cs50 pset5,拼写器)

尝试将字典加载到内存时C中出现分段错误(cs50 pset5,拼写器),c,memory,segmentation-fault,cs50,C,Memory,Segmentation Fault,Cs50,我已经部分完成了cs50的pset5,但每次我尝试运行我的程序时,由于某种原因,我都会遇到一个SEGFULT 在load函数中,我打开字典文件,并通过调用init_table初始化哈希表。然后,我使用fscanf扫描字典文件,为字典中的每个单词创建一个节点*n,并将单词从dict_word复制到此节点。然后,我使用基于djb2的哈希函数来存储该节点单词的索引 如果table[index]==NULL,那么我将table[index]和名为head的节点都设置为node n,并将下一个地址设置为N

我已经部分完成了cs50的pset5,但每次我尝试运行我的程序时,由于某种原因,我都会遇到一个SEGFULT

在load函数中,我打开字典文件,并通过调用init_table初始化哈希表。然后,我使用fscanf扫描字典文件,为字典中的每个单词创建一个节点*n,并将单词从dict_word复制到此节点。然后,我使用基于djb2的哈希函数来存储该节点单词的索引

如果table[index]==NULL,那么我将table[index]和名为head的节点都设置为node n,并将下一个地址设置为NULL。否则,我将下一个节点设置为table[index],将table[index]设置为当前节点n

我还没有释放任何内存,因为这将在另一个名为unload的函数中完成,但我怀疑我当前的问题可能是由于不同的原因。任何帮助都将不胜感激

// Implements a dictionary's functionality

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

#include "dictionary.h"

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

// Number of buckets in hash table (A-Z)
const unsigned int N = 5381;

// Hash table
node *table[N];

// initialize hash table (set all values to NULL)
// reference video: https://youtu.be/2Ti5yvumFTU
void init_table()
{
    for (int i = 0; i < N; i++)
    {
        table[i] = NULL;
    }
}

// Hashes word to a number
// hash function: djb2
// retrieved from http://www.cse.yorku.ca/~oz/hash.html
unsigned int hash(const char *word)
{
    unsigned int hash_value = N;
    int c;

    while ((c = *word++))
    {
        hash_value = ((hash_value << 5) + hash_value) + c; /* hash * 33 + c */
    }
    return hash_value;
}

// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
    // open dictionary file, check if NULL
    FILE *dict_file = fopen(dictionary, "r");
    if (dict_file == NULL)
    {
        return false;
    }

    init_table();

    // create char for each dictionary word (max length + nul)
    char dict_word[LENGTH + 1];

    // create beginning node that serves as first item in linked list
    node *head;

    // scan until end of file
    while (fscanf(dict_file, "%s", dict_word) != EOF)
    {
            // create a node n for each word and copy string into it
            node *n = malloc(sizeof(node));
            if (n == NULL)
            {
                return false;
            }
            strcpy(n->word, dict_word);

            // hash the word and store as index (which tells which linked list to use)
            int index = hash(n->word);

            // if table[index] is NULL, set it and head as node n, set next node as NULL
            if (table[index] == NULL)
            {
                head = table[index] = n;
                n->next = NULL;
            }
            // otherwise set next node as table[index], table[index] as current node n
            else
            {
                n->next = head;
                table[index] = n;
            }
    }
    return true;
}

编辑:在阅读了Boris Lipschitz的答案后,我意识到了这个问题,并进一步学习了如何使用调试器来解决它。我修改了const unsigned int N=5381,并将N的值更改为25,以表示字母表中每个字母的一个bucket,尽管我可能稍后会更改此值以优化我的程序。对于我的散列函数,正如Boris所说,并没有什么可以阻止散列值超过N,所以我改变了返回散列值;要改为返回哈希值%N;,这将给我一个在表的适当范围内的输出。

哈希函数中绝对没有任何东西可以阻止它达到5381或更高。然后你用它来访问表。。。吊杆,分段故障


反向问题:为什么不在调试器中运行代码?你知道答案的速度比我们任何人都要快。

你能把整个dictionary.c发布出来,让别人编译/运行/调试它吗?谢谢,我会设法解决这个问题。我没有使用调试器的原因是因为我不完全确定如何使用它,也不认为它可以在这里使用。然而,我将研究GDB调试器,并尝试解决这个问题,一旦我能够找到答案,我将标记您的答案。