gpt4 book ai didi

c - 在拼写检查器中使用大小为 8 的未初始化值

转载 作者:行者123 更新时间:2023-11-30 16:44:14 26 4
gpt4 key购买 nike

我编写了一个拼写检查器,它使用 trie 来存储和检查单词是否拼写错误。它将文本文件字典加载到内存中,接受单词以检查拼写错误并卸载内存。程序编译成功,但运行时产生段错误。基于 valgrind,问题似乎是在我的插入函数中使用了未初始化的值。

//If word not present, inserts word into trie
//If the word is a prefix of a node, marks the "leaf node" (end-of-word node)
void insert(struct node *root, const char *word)
{
int length = strlen(word);
int index = 0;

//start from root node
struct node *tempNode = root;

for(int i = 0; i < length; i++)
{
//if the current letter in word is a letter
if(word[i] != '\'')

//convert the alphabet to it's respective index number
index = CHAR_TO_INDEX(tolower(word[i]));

else
//assign index number 27 (for apostrophe)
index = INPUT_SIZE;

//create a new node if path doesn't exist (is NULL)
if(!(tempNode->children[index]))
tempNode->children[index] = getNode();

//go to next node
tempNode = tempNode->children[index];
}
//mark last node as leaf
tempNode->isWord = true;
}

insert(将单词放入 trie 中)由 load 调用(将单词从字典 txt 文件移动到内存中):

bool load(const char *dictionary)
{
//initialise variables
char ch;
char word[LENGTH] = "";
int counter = 0;

struct node *root = getNode();

//open file to start inserting words
FILE *file = fopen(dictionary, "r");

//load words in dictionary into memory
while (EOF)
{
while((ch = fgetc(file)) != '\n')
{
word[counter] = ch;
counter++;
}
//whole word found, insert word and reset counter, increment word count
insert(root, word);
counter = 0;
word_Count++;
}

//close all open files if EOF is reached, else loading has failed- return false
if(EOF == true)
{
fileLoaded = true;
fclose(file);
return true;
}
else return false;
}

和 getNode() 创建一个初始化为 NULL 的新节点:

    //Returns new trie node initialised to NULL
struct node *getNode(void)
{
//initialise new node
struct node *newNode = NULL;

newNode = malloc(sizeof(struct node));

//proceed if enough memory to allocate
if(newNode)
{
//initialise pointers
for(int i = 0; i < INPUT_SIZE; i++)
newNode->children[i] = NULL;

newNode->isWord = false;
}
else return false;

return newNode;
}

结构体节点的定义:

    //Returns new trie node initialised to NULL
struct node *getNode(void)
{
//initialise new node
struct node *newNode = NULL;

newNode = malloc(sizeof(struct node));

//proceed if enough memory to allocate
if(newNode)
{
//initialise pointers
for(int i = 0; i < INPUT_SIZE; i++)
newNode->children[i] = NULL;

newNode->isWord = false;
}
else return false;

return newNode;
}

根据 valgrind 的错误:

    Conditional jump or move depends on uninitialised value(s)
==9334== at 0x4011DD: insert (dictionary.c:84)
==9334== by 0x4014D1: load (dictionary.c:188)
==9334== by 0x40095D: main (speller.c:40)
==9334== Uninitialised value was created by a heap allocation
==9334== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9334== by 0x4010CB: getNode (dictionary.c:40)
==9334== by 0x4011E7: insert (dictionary.c:85)
==9334== by 0x4014D1: load (dictionary.c:188)
==9334== by 0x40095D: main (speller.c:40)
==9334==
==9334== Use of uninitialised value of size 8
==9334== at 0x4011D5: insert (dictionary.c:84)
==9334== by 0x4014D1: load (dictionary.c:188)
==9334== by 0x40095D: main (speller.c:40)
==9334== Uninitialised value was created by a heap allocation
==9334== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9334== by 0x4010CB: getNode (dictionary.c:40)
==9334== by 0x4011E7: insert (dictionary.c:85)
==9334== by 0x4014D1: load (dictionary.c:188)
==9334== by 0x40095D: main (speller.c:40)
==9334==
==9334== Invalid read of size 8
==9334== at 0x4011D5: insert (dictionary.c:84)
==9334== by 0x4014D1: load (dictionary.c:188)
==9334== by 0x40095D: main (speller.c:40)
==9334== Address 0x91 is not stack'd, malloc'd or (recently) free'd
==9334==
==9334==
==9334== Process terminating with default action of signal 11 (SIGSEGV)
==9334== Access not within mapped region at address 0x91
==9334== at 0x4011D5: insert (dictionary.c:84)
==9334== by 0x4014D1: load (dictionary.c:188)
==9334== by 0x40095D: main (speller.c:40)

valgrind 使用 --leak-check=full、--leak-check=full 和 --show-leak-kinds=all 运行。我尝试引用以前的帖子中的类似错误,但上下文的差异使得很难确定我应该做什么。第 84 行是 if(!(tempNode->children[index]))。 (对我来说)这似乎是问题的根本原因。

谢谢!

最佳答案

while((ch = fgetc(file)) != '\n')
{
word[counter] = ch;
counter++;
}
//whole word found, insert word and reset counter, increment word count
insert(root, word);

这是导致未定义行为的代码部分。

您的字符串 word 不是 null 终止的,但 insert 期望它是(因为它所做的第一件事是调用 strlen ,它期望一个空终止字符串)。

简单的修复就是

word[counter] = '\0';

在调用insert之前假设一切都在边界内。

关于c - 在拼写检查器中使用大小为 8 的未初始化值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44631058/

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