2009-10-04 50 views
10

我注意到有時在C程序中,如果我們在分割錯誤之前的任何位置有代碼printf,它不會打印。這是爲什麼?分割錯誤問題

+0

我經常看到非母語英語的用戶使用「我對...有懷疑」這個短語。我不希望看到母語爲英語的人開始使用「懷疑」這個詞的不恰當用法。 – Rob 2010-02-16 03:44:17

回答

20

這是因爲printf()的輸出被緩衝。您可以在printf之後立即添加fflush(stdout);並打印。你

也可以這樣做:

fprintf(stderr, "error string"); 

因爲stderr不會被緩衝。

There's also a related question

5

如果在printf之後發生分段錯誤太快並且輸出緩衝區未刷新,您將看不到printf的效果。

5

大多數libc實現緩衝printf輸出。將換行符(\ n)附加到輸出字符串以強制刷新緩衝區內容通常就足夠了。

+3

這是不夠的。你需要調用fflush(); – 2009-10-04 03:23:25

+1

除非它被重定向到一個文件,在這種情況下,它可能是更傳統的緩衝而不是行緩衝。 – 2009-10-04 03:23:51

+0

好點,我認爲線路緩衝沒有很好的理由,謝謝。 – Falaina 2009-10-04 20:45:21

3

您可以在printf後立即刷新輸出緩衝區,以確保它在發生seg故障之前發生。例如。 fflush(標準輸出)

3

隨機提示:如果您嘗試調試分段錯誤,請務必嘗試valgrind。它使它更容易!

0

你已經得到了許多答案,指出輸出流的緩衝。

無論好壞,儘管如此,這並不是唯一的可能性。分段錯誤意味着操作系統檢測到你做了錯誤的事情,通常寫在分配的內存外面。至少在當前/之前檢測到的情況下/在這種情況下,在這種情況下,在這種情況下,任何事情都可以改變程序在內部進行的足夠程度的操作,以防止檢測到問題。

例如,段錯誤可能是由通過未初始化的指針寫入引起的 - 碰巧保存了某個值(可能是一個小整數),因爲您之前調用的函數先前將該值留在了正確的位置在堆棧上,當調用後面的函數時,並且使用與指針相同的值時,它(合理可靠地)包含操作系統檢測到的值,這是您不允許寫入的地方。然而,對printf進行調用可能意味着你在沒有初始化的情況下在堆棧上留下了一些完全不同的值。你仍然在寫一些你不應該寫的東西,但它現在可能在某處,操作系統不知道知道你不應該寫。