簡體   English   中英

valgrind 對未初始化值的投訴會是誤報嗎?

[英]Could valgrind complaint about uninitialized values be a false positive?

所以我一直在自學 C,並希望從一開始就學習如何正確管理 memory 並編寫更好的代碼,我一直在運行 Valgrind。 這有助於我解決 memory 泄漏,但我似乎無法擺脫這種“條件跳轉或移動取決於未初始化的值/未初始化的值是由堆分配創建的”情況,盡管我已經縮小了范圍到這個代碼塊:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()    
{  
    char* test = (char*) malloc(3);
    strncpy(test, "123", 2);
    printf("%s\n", test);
    free(test);
    return 0;
}

當我使用---track-origins=yes運行 Valgrind 時,我得到了這個 output:

==91702== Conditional jump or move depends on uninitialised value(s) 
==91702==    at 0x100011507: strlen (mc_replace_strmem.c:282)
==91702==    by 0x1000AA338: puts (in /usr/lib/libSystem.B.dylib)
==91702==    by 0x100000EFA: main (valgrind_test.c:10)
==91702==  Uninitialised value was created by a heap allocation
==91702==    at 0x100010345: malloc (vg_replace_malloc.c:236)
==91702==    by 0x100000EEA: main (valgrind_test.c:8)

這對我來說似乎是一個誤報,但我對自己的知識沒有足夠的信心將其注銷。 也許我分配錯誤或使用 strncpy 錯誤? 我不確定。

提前致謝

不,這是損壞的代碼。

您有一個帶有 3 個未初始化字符的 memory 塊。 然后將"12"復制到其中,並且不要終止。 當心strncpy()

我引用文檔

strncpy() function 類似,只是復制的 src 不超過 n 個字節。 因此,如果 src 的前 n 個字節中沒有 null 字節,則結果不會以空值結尾。

由於源的前 2 個字符內沒有終止,因此目標沒有終止。

使用strcpy()strncpy()的慣用方式:

如果您知道緩沖區有空間容納字符串加上 NUL 終止符,則可以使用strcpy() 這可能會使用常量,或者在代碼中進行檢查(您應該確保檢查是正確的)。

否則,您可以執行以下操作:

strncpy(dest, src, length);
dest[length - 1] = '\0';

它有以下缺點:

  • 它可以截斷字符串。
  • 它可能效率低下,因為它總是填充length字節。

還有 OpenBSD 的strlcpy()

strcpy()/strncpy()的任何其他使用都可能是可疑的,您應該仔細查看它們。

底線:避免 C 字符串函數用於任何中等復雜的,嘗試使用一些庫來動態分配字符串。 Qmail/Postfix 自己推出,GNU 有obstacks

您的字符串沒有終止符,因此 valgrind 在抱怨時可能是正確的。 改變:

strncpy(test, "123", 2);

至:

strcpy(test, "12");

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM