错误 valgrind,但没有内存泄漏
error valgrind, but no memory leak
我得到了有关使用 malloc、calloc 或将子项分配给 NULL 来解决我的问题的建议,但实际上我所做的一切似乎都不起作用。我在这方面工作了很长时间,以至于我无法真正理解需要发生的事情。所以一些帮助将不胜感激
这是我的代码:
typedef struct trie
{
bool is_word;
struct trie* children[27];
}
trie;
trie* root = NULL;
int wordCount = 0;
int trie_pos;
/**
* Returns true if word is in dictionary else false.
*/
bool check(const char* word)
{
trie* current = root;
for (int i = 0; word[i] != '[=10=]'; i++)
{
int letter = tolower(word[i]);
if (word[i] == '\'')
{
letter = 'z' - 'a' + 1;
}
else
{
letter = letter - 'a';
}
if (current -> children[letter] == NULL)
{
return false;
}
else
{
current = current -> children[letter];
}
}
if (current -> is_word == true)
{
return true;
}
else
{
return false;
}
//return false;
}
/**
* Loads dictionary into memory. Returns true if successful else false.
*/
bool load(const char* dictionary)
{
FILE *source = fopen(dictionary, "r");
if (source == NULL)
{
return false;
}
// malloc memory for firstNade
root = malloc(sizeof(trie));
int character = 0;
// use trie* current as cursor
trie* current = NULL;
//loop through dictionary until end of file EOF
while(fgetc(source) != EOF)
{
fseek(source, -1, SEEK_CUR);
// set cursor to firstNode
current = root;
//loop through characters until \n
for (character = fgetc(source); character != '\n'; character = fgetc(source))
{
// if apostrophes, set character to z+1
if (character == '\'')
{
character = 'z' -'a' + 1;
}
else
{
character = character - 'a';
}
// If the character is not in trie...
if (current->children[character] == NULL)
{
// ... malloc a new node and go there
current->children[character] = malloc(sizeof(trie));
current = current->children[character];
}
else // ... but if it is, go to the existing node
{
current = current->children[character];
}
}
current->is_word = true;
wordCount++;
}
fclose(source);
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.
*/
void unloadHelper(struct trie* currNode)
{
for(int i = 0; i < 27; i++)
{
if(currNode->children[i] !=NULL)
{
unloadHelper(currNode->children[i]);
}
}
free(currNode);
}
/**
* Unloads dictionary from memory. Returns true if successful else false.
*/
bool unload(void)
{
unloadHelper(root);
return true;
}
这是我的 valgrind 输出的第一部分:
==24410== Conditional jump or move depends on uninitialised value(s)
==24410== at 0x804912B: load (dictionary.c:106)
==24410== by 0x8048745: main (speller.c:45)
==24410== Uninitialised value was created by a heap allocation
==24410== at 0x4006AB1: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==24410== by 0x804907D: load (dictionary.c:79)
==24410== by 0x8048745: main (speller.c:45)
valgrind 输出非常清楚...您正在访问未初始化的值。
root = malloc(sizeof(trie)); // uninitialized space
// ...
current = root;
现在 current->
任何东西 都未初始化。但是然后你去了:
if (current->children[character]
读取未初始化的变量current->children[character]
.
您的代码似乎假设未初始化的指针为 NULL,但事实并非如此。或许可以通过添加以下函数来解决此问题:
struct trie *new_node(void)
{
struct trie *node = malloc(sizeof(trie));
if ( !node ) exit(EXIT_FAILURE);
node->is_word = false;
for (size_t i = 0; i < sizeof node->children / sizeof node->children[0]; ++i)
node->children[i] = NULL;
return node;
}
创建节点时调用:
root = new_node();
current->children[character] = new_node();
我得到了有关使用 malloc、calloc 或将子项分配给 NULL 来解决我的问题的建议,但实际上我所做的一切似乎都不起作用。我在这方面工作了很长时间,以至于我无法真正理解需要发生的事情。所以一些帮助将不胜感激 这是我的代码:
typedef struct trie
{
bool is_word;
struct trie* children[27];
}
trie;
trie* root = NULL;
int wordCount = 0;
int trie_pos;
/**
* Returns true if word is in dictionary else false.
*/
bool check(const char* word)
{
trie* current = root;
for (int i = 0; word[i] != '[=10=]'; i++)
{
int letter = tolower(word[i]);
if (word[i] == '\'')
{
letter = 'z' - 'a' + 1;
}
else
{
letter = letter - 'a';
}
if (current -> children[letter] == NULL)
{
return false;
}
else
{
current = current -> children[letter];
}
}
if (current -> is_word == true)
{
return true;
}
else
{
return false;
}
//return false;
}
/**
* Loads dictionary into memory. Returns true if successful else false.
*/
bool load(const char* dictionary)
{
FILE *source = fopen(dictionary, "r");
if (source == NULL)
{
return false;
}
// malloc memory for firstNade
root = malloc(sizeof(trie));
int character = 0;
// use trie* current as cursor
trie* current = NULL;
//loop through dictionary until end of file EOF
while(fgetc(source) != EOF)
{
fseek(source, -1, SEEK_CUR);
// set cursor to firstNode
current = root;
//loop through characters until \n
for (character = fgetc(source); character != '\n'; character = fgetc(source))
{
// if apostrophes, set character to z+1
if (character == '\'')
{
character = 'z' -'a' + 1;
}
else
{
character = character - 'a';
}
// If the character is not in trie...
if (current->children[character] == NULL)
{
// ... malloc a new node and go there
current->children[character] = malloc(sizeof(trie));
current = current->children[character];
}
else // ... but if it is, go to the existing node
{
current = current->children[character];
}
}
current->is_word = true;
wordCount++;
}
fclose(source);
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.
*/
void unloadHelper(struct trie* currNode)
{
for(int i = 0; i < 27; i++)
{
if(currNode->children[i] !=NULL)
{
unloadHelper(currNode->children[i]);
}
}
free(currNode);
}
/**
* Unloads dictionary from memory. Returns true if successful else false.
*/
bool unload(void)
{
unloadHelper(root);
return true;
}
这是我的 valgrind 输出的第一部分:
==24410== Conditional jump or move depends on uninitialised value(s)
==24410== at 0x804912B: load (dictionary.c:106)
==24410== by 0x8048745: main (speller.c:45)
==24410== Uninitialised value was created by a heap allocation
==24410== at 0x4006AB1: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==24410== by 0x804907D: load (dictionary.c:79)
==24410== by 0x8048745: main (speller.c:45)
valgrind 输出非常清楚...您正在访问未初始化的值。
root = malloc(sizeof(trie)); // uninitialized space
// ...
current = root;
现在 current->
任何东西 都未初始化。但是然后你去了:
if (current->children[character]
读取未初始化的变量current->children[character]
.
您的代码似乎假设未初始化的指针为 NULL,但事实并非如此。或许可以通过添加以下函数来解决此问题:
struct trie *new_node(void)
{
struct trie *node = malloc(sizeof(trie));
if ( !node ) exit(EXIT_FAILURE);
node->is_word = false;
for (size_t i = 0; i < sizeof node->children / sizeof node->children[0]; ++i)
node->children[i] = NULL;
return node;
}
创建节点时调用:
root = new_node();
current->children[character] = new_node();