C 中 Trie 实现中的分段错误
Posted
技术标签:
【中文标题】C 中 Trie 实现中的分段错误【英文标题】:Segmentation Fault in Trie implementation in C 【发布时间】:2017-08-19 00:40:11 【问题描述】:我正在尝试实现一个 trie 数据结构来对给定的文本文件进行拼写检查。目前,它似乎适用于文件中的几个单词,然后它达到了段错误。我尝试调试以找到罪魁祸首,但我发现“字母”的值保留了看似随机的负值(它应该在 1 到 27 之间,包括在内)。通常,在我启动程序后,seg fault 问题几乎立即出现,所以我不确定为什么这个问题会在程序中间弹出。
/**
* Implements a dictionary's functionality.
*/
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "dictionary.h"
//create global root node
Trienode *root;
//create word counter for size() function
unsigned int wordcount = 0;
//creates an empty node
Trienode * newnode()
Trienode *nnode = NULL;
nnode = (Trienode *)malloc(sizeof(Trienode));
//initialize new node with null pointers and values
nnode -> parent = NULL;
for(int i = 0; i < 27; i++)
nnode -> children[i] = NULL;
return nnode;
void cleartrie(Trienode *head)
//if child node exists, free it, else continue with next iteration in for loop
if(head)
for(int i = 0; i < 27; i++)
cleartrie(head -> children[i]);
free(head);
head = NULL;
/**
* Returns true if word is in dictionary else false.
*/
bool check(const char *word)
int i = 0;
int letter;
Trienode *head = root;
while(word[i] != '\0')
if(isalpha(word[i]))
letter = word[i] - 'a';
else //it must be an apostrophe
letter = word[i] - 13;
if(!(head -> children[letter]))
return false;
else //a pointer must exist
head = head -> children[letter];
i++;
return true;
/**
* Loads dictionary into memory. Returns true if successful else false.
*/
bool load(const char *dictionary)
//open file
FILE *infile = fopen(dictionary, "r");
Trienode *parnode; //parent node
root = newnode();
Trienode *curnode = root; //current node
int letter = 0;
//while not end of file, read words
while(fgetc(infile) != EOF)
//while not end of word, read letters
for(;;)
int c;
//read current letter in file
c = fgetc(infile);
//convert input char to corresponding array location (a - z = 0-25, apostrophe = 26)
if(isalpha(c))
letter = c - 'a';
else if (c == '\'')
letter = c - 13;
//if end of string, exit loop
else if (c == '\0')
//end of word, so endofstring = true
wordcount++;
break;
//move to next letter if not either apostrophe or alphabetical
else
break;
//if pointer to letter of word doesn't exist, create new node
if(curnode -> children[letter] == NULL)
curnode -> children[letter] = newnode();
//child node is the new current node
parnode = curnode;
curnode = curnode -> children[letter];
curnode -> parent = parnode;
//return to root node
curnode = root;
fclose(infile);
return true;
/**
* Returns number of words in dictionary if loaded else 0 if not yet loaded.
*/
unsigned int size(void)
return wordcount;
/**
* Unloads dictionary from memory. Returns true if successful else false.
*/
bool unload(void)
cleartrie(root);
if (root == NULL)
return true;
return false;
对文字墙感到抱歉,但大部分内容只是为了提供上下文(我希望如此)。段错误错误发生在检查辅助函数的 if(!(head -> children[letter])) 行。
提前致谢!
【问题讨论】:
我看不到您的代码中的 Trienode 是什么。是结构体吗? 您使用了调试器吗?在您的代码中的哪些点准确地发生了设置错误(调试器应该告诉您)?您在哪里看到letter
的值出错了?由于这是部分代码列表(我不建议在不缩小问题范围的情况下将所有代码都放入其中)很难说问题只是“查看”它的位置。进行更多调试并缩小范围。
使用 valgrind。它会告诉你问题出在哪里。
请注意,点.
和箭头->
运算符绑定得非常紧密,不应在两边写上空格。
【参考方案1】:
我怀疑您的测试文件可能包含一些大写字母。如果是这种情况,那么减去'a'
以尝试重新映射您的字母将导致负数,因为'A' < 'a'
。看看ASCII Table。首先将字母转换为小写应该可以解决您的问题。
【讨论】:
以上是关于C 中 Trie 实现中的分段错误的主要内容,如果未能解决你的问题,请参考以下文章