错误valgrind,但没有内存泄漏

时间:2015-03-13 00:01:15

标签: c valgrind

我建议用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] != '\0'; 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)

1 个答案:

答案 0 :(得分:3)

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();