gpt4 book ai didi

c- sysmalloc 断言问题

转载 作者:行者123 更新时间:2023-11-30 16:38:41 25 4
gpt4 key购买 nike

我希望有人能帮助我理解我哪里出了问题。我正在实现一个程序来检查拼写正确性。在此过程中,我使用 trie 数据结构将字典文本文件加载到内存中以检查单词。

总体而言,它似乎按预期运行,但在加载尽可能长的单词(即 pneumonoultramicrooscopysilicovolcanoconiosis)时,我遇到了很多问题。我不明白为什么,但首先让我展示一些代码 -

/**
* 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 ....

再次感谢大家的帮助!对于我的问题格式不正确,我深表歉意,以后我会更好地遵守 SO 准则。

最佳答案

你的

  char *word = (char *) malloc((LENGTH + 1) * sizeof(char));

后面没有对 malloc 失败进行测试;您需要添加:

  if (!word) { perror("malloc word"); exit(EXIT_FAILURE); }

之前

          if (fscanf(dict, "%s", word) == EOF)

自从使用 fscanf%sNULL上指针错误(可能是 undefined behavior )。

顺便说一句, fscanf 的最新版本(或使用 dynamic memory TR )接受 %ms读取字符串时分配的说明符。在这些系统上您可以:

 char*word = NULL;
if (fscanf(dict, "%ms", &word) == EOF))
break;

有些系统有 getline ,参见this .

最后,使用所有警告和调试信息进行编译(gcc -Wall -Wextra -g 使用 GCC),改进代码以消除警告,并使用调试器 gdbvalgrind .

顺便说一句pneumonoultramicroscopesilicovolcanoconiosis有45个字母。您需要一个额外的字节作为终止 NUL (否则您将得到 buffer overflow )。所以你的LENGTH应该至少为 46(我建议选择稍大一些的值,也许是 64;事实上,我建议系统 C dynamic memory allocation 并避免在 more robust style 中硬编码此类限制和代码,如下GNU coding standards)。

关于c- sysmalloc 断言问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47400374/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com