[C++] Valgrind 出現 Use of uninitialised value 錯誤訊息

[C++] Valgrind 出現 Use of uninitialised value 錯誤訊息

今天用 valgrind 偵測一下專案裡的 C++ 程式有沒有 memory leak,

結果出現了錯誤訊息 Use of uninitialised value,

不過出現的地方蠻怪的,最後是在 printf() 裡面用到:


==22618== Use of uninitialised value of size 8
==22618== at 0x68762AB: _itoa_word (_itoa.c:179)
==22618== by 0x6877325: vfprintf (vfprintf.c:1634)
==22618== by 0x687B800: buffered_vfprintf (vfprintf.c:2319)
==22618== by 0x687673D: vfprintf (vfprintf.c:1289)
==22618== by 0x5581150: PrintLog (in /test/liblogger.so)
==22618== Uninitialised value was created by a stack allocation
==22618== at 0x532F559: Scanner::Callback() (Scanner.cpp:307)

 

找了半天,後來發現是 printf() 裡面用到的格式化字串 (format string),

因為資料型態有點不正確,就導致了這個錯誤…

 

舉例來說,下面的程式裡,變數 major 和 minor 是 unsigned int 型態,

但我們用 %ld (long int) 的方式來顯示:

printf("eng_major_ver=%ld, eng_minor_ver=%ld", major, minor);

 

上面的程式就會在 valgrind 中出現 use of uninitialized data 的錯誤,

原因應該是 major 和 minor 這兩個 unsigned int (4 bytes) 被放在堆叠上,

但 %ld 會指引 printf() 認為變數是 long (8 bytes),

所以 printf() 會去堆叠上取一個 8 bytes 的資料出來用,

valgrind 就會偵測到它取到超出範圍、沒有初始化的堆叠資料了~

 

修正的方式就是使用正確的 %u 來對應 unsigned int,就不會有錯誤訊息了:

printf("eng_major_ver=%u, eng_minor_ver=%u", major, minor);

(本頁面已被瀏覽過 1,960 次)

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料