来自valgrind的未初始化值

时间:2015-11-13 06:15:59

标签: c memory struct valgrind

==2630== Conditional jump or move depends on uninitialised value(s)
==2630==    at 0x4E82D71: vfprintf (in /usr/lib64/libc-2.21.so)
==2630==    by 0x4E88E78: printf (in /usr/lib64/libc-2.21.so)
==2630==    by 0x400C0C: searchWord (T9.c:91)
==2630==    by 0x400A0A: main (T9.c:40) 

==2114==  Uninitialised value was created by a heap allocation
==2114==    at 0x4C28C50: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==2114==    by 0x400FD1: newStr (trie_node.c:125)
==2114==    by 0x400F8C: create_trie (trie_node.c:117)
==2114==    by 0x4009D5: main (T9.c:37)

我在valgrind中运行跟踪功能,上面有错误信息。我很确定我已经初始化了变量。 这是结构代码:

struct wordList* newStr(char* text) {
    char* word;
    struct wordList* tmp = (struct wordList*)malloc(sizeof(struct wordList));
    word = (char *)malloc(sizeof(char) * strlen(text) + 1);
    strncpy(word, text, strlen(text));
    tmp->str = word;
    tmp->next = NULL;
    return tmp;
}

T9.c第91行的代码:

struct wordList* cur;
if (cur && invalid == 0 && flag == 0) {
  printf("\t\'%s\'\n", cur->str);
 } 

更新

我修改了

中的strncpy行
    strncpy(word, text, strlen(text));

word = strncpy(word, text, strlen(text));

这解决了未初始化的问题,但是我收到了一条我不理解的新错误消息:

==3245== Invalid read of size 1
==3245==    at 0x4E82D71: vfprintf (in /usr/lib64/libc-2.21.so)
==3245==    by 0x4E88E78: printf (in /usr/lib64/libc-2.21.so)
==3245==    by 0x400C0C: searchWord (T9.c:91)
==3245==    by 0x400A0A: main (T9.c:40)
==3245==  Address 0x51f7d45 is 0 bytes after a block of size 5 alloc'd
==3245==    at 0x4C28C50: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==3245==    by 0x400FC1: newStr (trie_node.c:124)
==3245==    by 0x400F80: create_trie (trie_node.c:117)
==3245==    by 0x4009D5: main (T9.c:37)

2 个答案:

答案 0 :(得分:3)

我需要查看更多代码,但是虽然我不确定这正是valgrind所抱怨的,但是你的代码确实存在一个主要错误:

strncpy(word, text, strlen(text));

你不是在终止你的字符串,你只是复制实际的字符。它特别有趣,因为有一个函数已经负责分配正确的内存量和复制字符串:strdup

强制警告也要停止投放malloc的返回值。

答案 1 :(得分:1)

您必须查看完整错误(不仅仅是第二个错误)。根据经验,您应该从上到下阅读错误,因为后续错误可能是前者的结果(或前者的解释)。第二条消息只是告诉你malloc分配的内存没有被初始化,这是预期的 - 它只是对第一个的修正。

当你使用分配的空间而不填充有用的东西时,错误就在于此。错误在于新发布的代码,cur->str指向的块可能未初始化。

由于您使用strncpy,故障有点棘手。它只会复制strlen(text)个字节,从而跳过空终止符。你已经为它腾出了空间但它没有被复制,因此分配的缓冲区的最后一个字节没有被初始化(当vfprintf遍历字符串并到达空终结符应该的字节时,就会发生错误。 / p>

要明确strncpy(dst, src, cnt)的作用。它复制最多cnt个字节(包括空终止符),如果包含空终止符的src字符串不超过cnt字节,它将复制完整字符串。否则,它只会复制字符串的第一个cnt字节, null终止dst