2014-02-08 59 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