为啥哈希函数会给出分段错误?
Posted
技术标签:
【中文标题】为啥哈希函数会给出分段错误?【英文标题】:Why does the hash function give a segmentation fault?为什么哈希函数会给出分段错误? 【发布时间】:2021-04-27 17:12:39 【问题描述】:我试图制作一个拼写检查程序,我首先必须将字典加载到内存中。为此,我尝试使用哈希表。当我对哈希表使用哈希函数时,程序显示分段错误。
// Implements a dictionary's functionality
#include <stdbool.h>
#include <errno.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
const unsigned int N = 6536;
// Hash table
node *table[N];
// Returns true if word is in dictionary, else false
bool check(const char *word)
//TODO
return false;
// Hashes word to a number
unsigned int hash(const char *word) //Hashed using djb2
unsigned long hash = 5381;
int c = 0;
while (c == *word++)
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
return hash;
// Loads dictionary into memory, returning true if successful, else false
bool load(const char *dictionary)
char *str = NULL;
FILE *dict = fopen(dictionary,"r");
node *temp = NULL;
if(dict == NULL)
//printf("Error: \n", strerror(errno));
return false;
for(int i = 0; i < N; i++)
table[i] = NULL;
while(fscanf(dict, "%s", str) != 1)
unsigned int key = hash(str);
temp = malloc(sizeof(node));
if(temp == NULL)
return false;
if(table[key] != NULL)
temp->next = table[key]->next;
strcpy(temp->word, str);
table[key]->next = temp;
free(temp);
else
table[key] = malloc(sizeof(node));
table[key]->next = NULL;
strcpy(table[key]->word, str);
fclose(dict);
printf("SUCCESS\n");
return true;
调试器显示段。 unsigned int key = hash(str);
发生故障。我想知道如何解决这个问题。
【问题讨论】:
为什么没有人发过minimal reproducible example? 循环语句while (c == *word++)
闻起来很腥。你的意思是while (c = *word++)
?否则,c
的值永远不会是零。
@AdrianMole 使用 while (c = *word++)
会导致编译器错误:dictionary.c:38:14: note: use '==' to turn this assignment into an equality comparison while (c = *word++)
while(fscanf(dict, "%s", str) != 1)
-- 我很确定你的意思是== 1
这里(“只要扫描一个单词成功......”)
在while
循环中使用赋值作为条件是允许的并且有时很有用:赋值产生一个值,即右侧的值,并将其评估为布尔值:0 表示假,其他一切都意味着真实。更常见的是将==
作为条件进行比较,并且在需要比较时使用 ans 赋值是很常见的。因此,编译器发出警告。您可以通过将赋值放在括号中来避免此警告:while ((c = *word++)) ...
。
【参考方案1】:
试试
char str[MAX_LEN];
而不是
char *str = NULL;
(在将MAX_LEN
定义为适合您的应用程序之后)。
正如 M Oehm 在评论中指出的那样,我认为您也可能错误地解释了 fscanf()
的返回值。
【讨论】:
在尝试存储字符串时声明字符数组和字符指针有区别吗? 当然有区别。该阵列已经存储了MAX_LEN
附加字符。空指针没有附加内存并且不能被取消引用。尝试通过此指针存储数据将不起作用并且可能会崩溃。
@MelPradeep @M Oehm 说了什么;)。以上是关于为啥哈希函数会给出分段错误?的主要内容,如果未能解决你的问题,请参考以下文章