我希望有人可以帮我理解我在哪里出错了。我正在实施一个检查拼写正确性的程序。在这个过程中,我使用trie数据结构将字典文本文件加载到内存中以检查单词。
总的来说,它似乎按预期运行,但是当加载最长的单词时,即加入肺炎微量纤维细胞病,我会遇到很多问题。我不明白为什么,但首先让我提出一些代码 -
/**
* Loads dictionary into memory. Returns true if successful else false.
*/
bool load(const char *dictionary)
{
FILE *dict = fopen(dictionary, "r");
if (dict == NULL)
{
fprintf(stderr, "Could not open %s dictionary file.\n", dictionary);
return false;
}
// Initialise the root t_node
root = (t_node *) malloc(sizeof(t_node));
if (root == NULL)
{
fprintf(stderr, "Could not allocate memory to trie structure.\n");
return false;
}
// Set all current values in root to NULL and is_word to false
for (int i = 0; i < ALPHA_SIZE; i++)
{
root->branch[i] = NULL;
}
root->is_word = false;
while (1)
{
// Create char aray to hold words from .txt dictionary file once read
char *word = (char *) malloc((LENGTH + 1) * sizeof(char));
if (fscanf(dict, "%s", word) == EOF)
{
free(word);
break;
}
t_node *cursor = root;
int len = strlen(word) + 1;
for (int i = 0; i < len; i++)
{
if (word[i] == '\0')
{
cursor->is_word = true;
cursor = root;
word_count++;
}
else
{
int index = (word[i] == '\'') ? ALPHA_SIZE - 1 : tolower(word[i]) - 'a';
if (cursor->branch[index] == NULL)
{
cursor->branch[index] = (t_node *) malloc(sizeof(t_node));
for (int j = 0; j < ALPHA_SIZE; j++)
{
cursor->branch[index]->branch[i] = NULL;
}
cursor->branch[index]->is_word = false;
}
cursor = cursor->branch[index];
}
}
free(word);
}
fclose(dict);
return true;
}
这是我将字典加载到内存中的整个函数。作为参考,我定义了trie结构并在此函数之前创建了根。 LENGTH定义为45以说明可能的最长单词。而ALPHA_SIZE是27包括小写字母加撇号。
正如我已经说过所有其他较短的单词,这个功能运作良好。但是,使用最长的单词,函数通过大约一半的单词起作用,在遇到sysmalloc断言问题然后中止之前,先起作单词变量的索引29。
我试图找到这里发生的事情,但我能看到的最多是它在 -
cursor->branch[index] = (t_node *) malloc(sizeof(t_node));
一旦到达第29个单词索引,但之前没有其他索引。我能找到的所有其他帖子都与提供此错误的函数有关,而这些函数根本不起作用,而不是大部分时间都有异常。
任何人都可以看到我不能做的以及我在此代码中犯的错误是什么?我感谢您的帮助,感谢大家花时间考虑我的问题。
*更新*
首先,我要感谢所有人的帮助。看到有多少人对我的问题作出回应以及他们做得多快,我感到非常惊喜!我不能对你们所有人的帮助表示感谢。特别是Basile Starynkevitch给了我很多信息并提供了很多帮助。
我非常尴尬地说,我已经找到了我的问题,而且在转向SO之前,我应该抓住一段时间。因此,我必须为使用每个人的时间而道歉,因为这些事情太愚蠢了。我的问题在这里撒谎 -
else
{
int index = (word[i] == '\'') ? ALPHA_SIZE - 1 : tolower(word[i]) - 'a';
if (cursor->branch[index] == NULL)
{
cursor->branch[index] = (t_node *) malloc(sizeof(t_node));
for (int j = 0; j < ALPHA_SIZE; j++)
{
cursor->branch[index]->branch[j] = NULL; // <<< PROBLEM WAS HERE
}
cursor->branch[index]->is_word = false;
}
cursor = cursor->branch[index];
}
在我的代码中,我最初有&#39; cursor-&gt; branch [index] - &gt; branch [i] = NULL&#39;我在哪里迭代&#39; int j&#39;在那个循环中,不是我......
Sooooo再次感谢大家的帮助!对于格式错误的问题,我很抱歉,将来我会更好地遵守SO指南。
答案 0 :(得分:0)
您
char *word = (char *) malloc((LENGTH + 1) * sizeof(char));
后面没有malloc
失败的测试;你需要添加:
if (!word) { perror("malloc word"); exit(EXIT_FAILURE); }
前
if (fscanf(dict, "%s", word) == EOF)
因为在fscanf
指针上使用%s
NULL
是错误的(undefined behavior,可能)。
BTW,最新版本的fscanf
(或dynamic memory TR)接受%ms
说明符,以便在阅读时分配字符串。在那些系统上你可以:
char*word = NULL;
if (fscanf(dict, "%ms", &word) == EOF))
break;
最后,编译所有警告和调试信息(gcc -Wall -Wextra -g
与GCC),改进代码以获取警告,并使用调试器gdb
和valgrind。
LENGTH
至少应该是46(我建议选择稍微大一点的东西,也许是64;实际上我建议系统地使用 C dynamic memory allocation并避免硬编码这样的限制和在robust style之后的GNU coding standards更多代码。