2014-02-08 37 views
0

我跑valgrind with --track-origins = yes,所以我认为它会显示有关未初始化变量的错误,如: valgrind --track-origins = yes ./pointer 也是有可能永久编辑valgrind的设置在一个文件的种类?获取valgrind显示常见错误

我跑它的代码是这样的:

#include <stdio.h> 
int main(){ 
    int age = 10; 
    int height; 
    printf("I am %d years old.\n"); 
    printf("I am %d inches tall.\n"); 

return 0; 

} 

这是Valgrind的我的结果

==12005== Memcheck, a memory error detector 
==12005== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al. 
==12005== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info 
==12005== Command: ./pointer 
==12005== 
I am -16776936 years old. 
I am 2147483633 inches tall. 
==12005== 
==12005== HEAP SUMMARY: 
==12005==  in use at exit: 0 bytes in 0 blocks 
==12005== total heap usage: 0 allocs, 0 frees, 0 bytes allocated 
==12005== 
==12005== All heap blocks were freed -- no leaks are possible 
==12005== 
==12005== For counts of detected and suppressed errors, rerun with: -v 
==12005== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2) 

我期待这样的事情(从“学习C硬盘的方式”)

==3082== Memcheck, a memory error detector 
==3082== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al. 
==3082== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info 
==3082== Command: ./ex4 
==3082== 
I am -16775432 years old. 
==3082== Use of uninitialised value of size 8 
==3082== at 0x4E730EB: _itoa_word (_itoa.c:195) 
==3082== by 0x4E743D8: vfprintf (vfprintf.c:1613) 
==3082== by 0x4E7E6F9: printf (printf.c:35) 
==3082== by 0x40052B: main (ex4.c:11) 
==3082== 
==3082== Conditional jump or move depends on uninitialised value(s) 
==3082== at 0x4E730F5: _itoa_word (_itoa.c:195) 
==3082== by 0x4E743D8: vfprintf (vfprintf.c:1613) 
==3082== by 0x4E7E6F9: printf (printf.c:35) 
==3082== by 0x40052B: main (ex4.c:11) 
==3082== 
==3082== Conditional jump or move depends on uninitialised value(s) 
==3082== at 0x4E7633B: vfprintf (vfprintf.c:1613) 
==3082== by 0x4E7E6F9: printf (printf.c:35) 
==3082== by 0x40052B: main (ex4.c:11) 
==3082== 
==3082== Conditional jump or move depends on uninitialised value(s) 
==3082== at 0x4E744C6: vfprintf (vfprintf.c:1613) 
==3082== by 0x4E7E6F9: printf (printf.c:35) 
==3082== by 0x40052B: main (ex4.c:11) 
==3082== 
I am 0 inches tall. 
==3082== 
==3082== HEAP SUMMARY: 
==3082==  in use at exit: 0 bytes in 0 blocks 
==3082== total heap usage: 0 allocs, 0 frees, 0 bytes allocated 
==3082== 
==3082== All heap blocks were freed -- no leaks are possible 
==3082== 
==3082== For counts of detected and suppressed errors, rerun with: -v 
==3082== Use --track-origins=yes to see where uninitialised values come from 
==3082== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 4 from 4) 

回答

0

一般来说,我不认为这是保证 Valgrind会发现这样的事情。如果获取但未传递的可变参数来自堆栈,那么堆栈的那部分可能已经被初始化为“偶然”。

但是,在这种特殊情况下,您可能会看到AMD64 ABI的影响,而您引用的示例似乎是x86(从地址不超过32位判断)。由于AMD64 ABI在寄存器中传递最多六个参数,因此printf甚至不会触及内存以获取参数,直到您给出更多的参数为止。

举例来说,我想这个方案:

#include <stdio.h> 

int main(int argc, char **argv) 
{ 
    printf("%i %i %i %i %i %i %i\n"); 
    return(0); 
} 

由于只有6 %i规格,Valgrind的警告的什么都没有,而有七个,我得到警告。我很确定这是因为参数在寄存器中传递。 (我承认,但是,我会认为应该已经足够了,但是,看看格式字符串本身如何消耗一个寄存器,我不能很好地解释这种效果。我在上面提到,第一个非注册参数恰好在内存中初始化了。)

+0

我试过了,它对我来说似乎也是一样,谢谢你的帮助 – guano

0

我禁不住注意到你的printf调用实际上并没有使用变量。你注意到了吗?

这可能是它不工作的原因。

+0

我改了这行:printf(“我是%d英寸高。\ n”); - > printf(“我是%d英寸高。\ n”,高度);这是你的意思吗? – guano

+0

另外,我认为Dolda2000正在开发一些当它尝试使用printf打印7个变量的绝对工作, – guano