c - 瓦尔格林德+C : conditional jump or move depends on uninitialised value(s)

标签 c valgrind cs50

我收到此错误:

Conditional jump or move depends on uninitialised value(s)

我的意思是,我用于条件语句的值未初始化。但是,我相信该值要初始化。我不确定到底是什么问题。帮助将不胜感激。

该代码用于 CS50 第 5 周的作业,用于存储可以添加值的字典,并可用于检查文本是否存在拼写错误。我正在尝试存储字典条目。

编辑

感谢在这里收到的帮助,我能够解决之前出现的错误。我现在已经将最小示例更改为更接近真实情况(现在它从名为“dictionary/small”的文件而不是硬编码数组中获取单词值),现在我遇到了另一个问题。 Valgrind 指向直线

if (word == NULL || strcmp(word, "") == 0)

bool add_word(char *word)中。它给出了这个错误:

==5452== Use of uninitialised value of size 8
==5452==    at 0x4C2F1B1: strcmp (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5452==    by 0x400B4C: add_word (test.c:81)
==5452==    by 0x400AA3: load (test.c:64)
==5452==    by 0x4008C6: main (test.c:26)
==5452==  Uninitialised value was created by a stack allocation
==5452==    at 0x4008E4: load (test.c:30)

代码如下:

#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>

#define LINES 45
#define LENGTH 143092

typedef struct node
{ 
    bool is_word;
    struct node *children[27];
}
node;

bool load(const char *dictionary);
bool unload(void);
bool add_word(char *word);
int char_to_child(char c);
char *strdup(const char *s);

node *root;

int main(void)
{
    load("dictionaries/small");
}

bool load(const char *dictionary)
{
    char *words[LINES];

    FILE *fp = fopen(dictionary, "r");
    if (fp == 0)
    {
        return false;
    }

    char buffer[LENGTH + 1];
    for (int i = 0; i < LINES && fgets(buffer, LENGTH * sizeof(char), fp); i++)
    {
        words[i] = NULL;
        if (strlen(buffer) <= LENGTH)
        {
            words[i] = strdup(buffer);
        }
    }  
    fclose(fp);     

    // create a try and add the words
    root = malloc(sizeof(node));
    if (!root)
    {
        return false;
    }
    root->is_word = NULL;
    for (int i = 0; i < 27; i++)
    {
        root->children[i] = NULL; 
    }

    for (int i = 0; i < LINES; i++)
    {
        if (add_word(words[i]) == false)
        {
            return false;
        }
        free(words[i]);
    }

    return true;
}

bool add_word(char *word) {
    node *ptr = root;

    if (ptr == NULL)
    {
        return false;
    }
    if (word == NULL || strcmp(word, "") == 0)
    {
        return false;
    }

    for (size_t i = 0; i < strlen(word); i++)
    {
        int letter = char_to_child(word[i]);

        if (letter < 27)
        {
            if (ptr->children[letter] == NULL)
            {
                node *new_node;
                new_node = malloc(sizeof(node));
                if (!new_node)
                {
                    return false;
                }
                new_node->is_word = false;
                for (int j = 0; j < 27; j++)
                {
                    new_node->children[j] = NULL;
                }

                ptr->children[letter] = new_node;
            }
            else
            {
                if (ptr->children[letter]->is_word != true)
                {
                    ptr->children[letter]->is_word = false;
                }
            }
            ptr = ptr->children[letter];
        }
    }
    ptr->is_word = true;


    return true;
}

int char_to_child(char c)
{
    if (c >= 'A' && c <= 'Z')
    {
        return c - 'A';
    }
    else if (c >= 'a' && c <= 'z')
    {
        return c - 'a';
    }
    else if (c == '\'')
    {
        return 26;
    }
    else 
    {
        return 27;
    }
}

最佳答案

问题是因为这段代码:

for (int i = 0; i < LINES; i++)
{
    if (add_word(words[i]) == false)

最终将阅读所有第一个LINES words 中的条目。然而,在这个早期的代码中:

for (int i = 0; i < LINES && fgets(buffer, LENGTH * sizeof(char), fp); i++)

fgets时你停止失败,并且如果 i < LINES-1此时,它意味着 words 中的一些指针。保持未初始化状态。那么你的 valgrind 错误来自 add_word(words[i])使用未初始化的指针。

要解决此问题,您可以首先初始化所有指针,或者记住 i 的值从第一个循环末尾开始,并使用相同的值结束第二个循环。

顺便说一句if (strlen(buffer) <= LENGTH)是多余的。 fgets调用已经保证了这一点,因为您指定了缓冲区大小 LENGTH .

关于c - 瓦尔格林德+C : conditional jump or move depends on uninitialised value(s),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45897189/

相关文章:

javascript - xmlHttpRequest 卡在就绪状态 1

C:我的函数中的变量无法识别,因为我的变量不是全局的

c++ - std::ifstream 读取大数的错误大小

c - 免费 : Invalid Size : Valgrind

CS50贪心算法

jQuery 创建一个自动完成表单

c - 是否可以动态选择 UNION 下的 2 个结构之一?

c - Linux 内核 : strncpy_from_user() copying too many bytes

c - 如何在C中检查给定路径中是​​否存在文件?

c++ - C++ sprintf删除未定义的行为