【发布时间】:2017-11-20 20:21:06
【问题描述】:
我希望有人可以帮助我了解我在哪里出错了。我正在实施一个程序来检查拼写正确性。在此过程中,我使用 trie 数据结构将字典文本文件加载到内存中以检查单词。
总体而言,它似乎按预期运行,但在加载尽可能长的单词时,我遇到了很多问题,即 pneumonoultramicroscopicsilicovolcanoconiosis。我不明白为什么,但首先让我介绍一些代码 -
/**
* 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];
}
在我的代码中,最初我有 'cursor->branch[index]->branch[i] = NULL' 我在那个循环中迭代了 'int j',而不是 i ....
Sooooo 再次感谢大家的帮助!对于我的问题格式不正确,我深表歉意,今后我会更好地遵守 SO 准则。
【问题讨论】:
-
这里不足以重现问题。请使用minimal reproducible example 更新您的问题。
-
不要将 malloc 的结果投射到 c 中。
-
在 valgrind 下运行(如果你在 linux 上)
-
顺便说一句,它是
malloc,而不是sysmalloc -
如何断言
len <= LENGTH