2013-10-24 49 views
0

我有以下功能,有時會打「檢測到堆棧粉碎」。但是當我修改sprintf()snprintf(nbytes_buf, sizeof(nbytes_buf), "%d", nbytes)時,問題就解決了。C snprintf sprintf堆棧粉碎檢測

'data'永遠不會超過1024個字節。所以,我認爲nbytes_buf [20]就足夠了。但是當'data'包含字符'>'時,我也會碰到「stack smashing detected」的問題。

有誰知道爲什麼?

int a(const char *data) 
{ 
    int nbytes; 
    char nbytes_buf[20]; 

    nbytes = strlen(data); 
    sprintf(nbytes_buf, "%d", nbytes); 

    /* do something else */ 
    return 0; 
} 
+0

如果修改爲您所說的'snprintf(nbytes_buf,sizeof(nbytes_buf),nbytes)',那麼您傳遞'nbytes'作爲格式字符串的地址,這顯然是不正確的。也許'snprintf(nbytes_buf,sizeof(nbytes_buf),「%d」,nbytes)'會更有建設性。 **編輯**:或更改問題中的代碼。這也起作用。 – WhozCraig

+0

謝謝。我已糾正。 – VincentHuang

+0

您是否正在使用這種格式的字符串,類型和您的真實代碼中的所有內容? –

回答

0

如果使用sprintf()緩衝區的大小應該足夠大,以包含整個結果字符串。 snprintf()將解決此問題,因爲如果結果字符串長於n-1個字符,則剩餘的字符將被丟棄並且不存儲。

因此,只有當您使用sprintf()並且字符串的大小大於n-1時,纔會收到錯誤"stack smashing detected"。如果使用snprintf(),即使字符串的大小大於n-1,問題也不會發生。

+0

「%d」如何創建比他預先分配的20個字符更長的結果? –

+0

是的傑裏,我創建了20個字符數組nbytes_buf [20]。我認爲對於我的應用來說,'數據'不會太長。 – VincentHuang

+0

@JerryJeremiah達到10000000000000000000,即0x8AC7230489E80000可以用64位'size_t'完成,但我真的很想要這個人的機器,如果它可以處理的話,更少的*有*,那麼大的字符串。 – WhozCraig

0

http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html 的的snprintf()函數,應等於的sprintf(),在加入其中指出由s提到的緩衝區的大小的參數n的。如果n爲零,則不應寫入任何內容,並且s可能是空指針。否則,*超出n-1st的輸出字節將被丟棄,而不是寫入數組, * nd空字節寫入實際寫入數組的字節末尾。