fread()导致Valgrind错误:"条件跳转或移动取决于未初始化的值"

时间:2017-12-01 23:16:30

标签: c valgrind

问题:

在工作中加载数据,但是当尝试从节点中检索存储的text_时,valgrind会引发"条件跳转"。 text_仍然可以正确检索并显示。

导致问题的原因:

这是代码片段是readFile()函数的一部分,这个特定的fread()会导致问题。

int readFile(char **text, ...)
    ...
    size_text = filesize - previous_position;
    *text = (char *)malloc(size_text + 1);
    fread(*text, 1, size_text, input);

Valgrind消息:

==18139== Conditional jump or move depends on uninitialised value(s)
==18139==    at 0x48303C7: __GI_strlen (vg_replace_strmem.c:455)
==18139==    by 0x48EA17F: vfprintf (vfprintf.c:1637)
==18139==    by 0x48EF955: printf (printf.c:33)
==18139==    by 0x108F6A: game (version-3.c:243)
==18139==    by 0x109085: main (version-3.c:287)
==18139==  Uninitialised value was created by a heap allocation
==18139==    at 0x482D27C: malloc (vg_replace_malloc.c:299)
==18139==    by 0x108BBC: readFile (version-3.c:125)
==18139==    by 0x108D4A: BuildTree (version-3.c:197)
==18139==    by 0x109074: main (version-3.c:286)
==18139== 

解决方案

添加空终止符可修复此错误。 最初的假设,它已经是空终止来自错误的终止符* text [size_text] =' \ 0&#39 ;; - >抛出错误 (* text)[size_text] =' \ 0&#39 ;; - >修复错误

1 个答案:

答案 0 :(得分:2)

错误不会发生在 fread() 中。它发生在__GI_strlen。这意味着该函数依赖于其逻辑的变量要么没有完全初始化,要么没有完全初始化。

因为你知道*strlen应该做什么(计算字符数,除了C字符串中的终止\0),你可以推断出问题所在:你有{{1一个特定大小的缓冲区,但包含malloc()终结符的字符串并没有完全占用它。因此缓冲区中存在尾随空间,这些空间被保留为单元,因此出现错误。

因此,检查返回值\0以确切确认读取了多少字节是个好主意。不能保证能够按要求读取尽可能多的元素(在您的情况下为字节):它可以返回错误,或者读取任何数量的元素,直到您指定的限制。

将null终结符显式放在缓冲区中是另一个好主意! (你错过了。)