为什么Valgrind抱怨printf而不是我的未初始化的计数器?

时间:2017-02-14 18:46:33

标签: c initialization valgrind

我刚刚开始使用Valgrind,我不确定我得到的错误信息应该是什么。例如,Valgrind给了我一个很长的警告链,关于printf()根据未初始化的内存进行跳转。显然问题不在printf()。相反,我的程序给了printf()污染的记忆。

我设法制作了以下MCVE:

#include <stdio.h>

int main(void)
{
    int d;
    d++;
    printf("%d\n", d);
    return 0;
}

这里的问题非常明显,问题在于d++。但是,Valgrind只检测并警告我下一行中未初始化的内存使用情况,其中包含6条消息

  

== 12178 ==有条件的跳跃或移动取决于未初始化的值(s)
  == 12178 ==在0x4E7F79D:vfprintf(vfprintf.c:1636)
  == 12178 == by 0x4E871F8:printf(printf.c:33)
  == 12178 == by 0x1086D1:main(mcve.c:7)

我用

编译了这个
  

gcc mcve.c -g -O0

我和Valgrind一起跑

  

valgrind --leak-check = yes ./a.out

然后我发现了--track-origins=yes。它试图提供帮助,但它很容易被指针迷失。例如,它不适用于下一个MCVE:

#include <stdio.h>

int f2(int *p)
{
    (*p)++;
    return *p;
}

int f1(void)
{
    int d;
    return f2(&d);
}

int main(void)
{
    printf("%d\n", f1());
    return 0;
}

这里它表示错误位于f1()的堆栈帧中。它有点乐于助人,但考虑到所涉及的性能损失,也许它不值得。

我可以做些什么来充分利用Valgrind?

1 个答案:

答案 0 :(得分:3)

Valgrind的一个深思熟虑的决定是抱怨 只是因为一些未初始化的内存被复制或类似。 只有在使用未初始化的内存改变时,它才会抱怨 您计划的行为。这种刻意的选择避免了很多误报错误。

参见http://www.valgrind.org/docs/manual/mc-manual.html#mc-manual.uninitvals 了解更多信息。