[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);