2011-07-27 156 views
2

我正在致力於一個項目,我調用一個觸發段錯誤的函數。我解決了這個問題,但是在這個過程中我注意到了以下幾點G ++編譯器:Segfault處理

當我的代碼是格式;

main(){ 
    ... 
    std::cout << "Looking for segfault\n"; // this does not print 
    buggyFunction(); // crashes in here 
    ... 
} 

buggyFunction(){ 
    ... 
    thing_that_causes_segfault; 
    ... 
} 

線「尋找段錯誤」不打印到性病,並在buggyFunction程序崩潰。很好,但是當我在buggyFunction()中添加一個cout行時;

main(){ 
    ... 
    std::cout << "Looking for segfault\n"; // this now *does* print 
    buggyFunction(); 
    ... 
} 

buggyFunction(){ 
    ... 
    std::cout << "Now we're INSIDE buggy function\n"; // this prints too 
    thing_that_causes_segfault; 
    ... 
} 

在越野車功能,兩行打印(然後它崩潰)。

爲什麼我們在輸出中看到這種差異,取決於額外的輸出呼叫的增加?它與流處理有關還是其他?我正在使用g ++(Ubuntu 4.4.3-4ubuntu5)4.4.3。

回答

7

原因是cout有一個緩衝區,它只會傳遞給系統函數並在緩衝區滿時寫入控制檯。你的第二次使用cout恰好溢出緩衝區,所以它調用操作系統並清空緩衝區。如果要確保輸出已離開緩衝區,則必須使用std::flush。您可以結束一行並使用std::endl刷新緩衝區。

+2

或者,您可以用'的std :: cerr',這是無緩衝(大概爲錯誤報告的目的)。 –

+1

即使使用「std :: endl」而不是「\ n」,仍然不能保證該行將被打印,但是使用'std :: endl'打印行的機率更好。兩個原因爲什麼這仍然可能無效:(1)可能還有其他緩衝正在進行,(2)SEGFAULT是對某種未定義行爲的迴應。對於未定義的行爲沒有保證。 –

+0

D'OH!我以前有一個endl(專門用來刷新流),但是在調試的某個時候它已經被刪除了,我忘了重新放入 - 我很少使用\ n。 – Alex

2

它與緩衝有關。你寫給cout的東西被附加到一個內部緩衝區,只有週期性的刷新。您可以通過將std::flush寫入流,或將"\n"替換爲<< std::endl來明確刷新緩衝區。

3

因爲您的行可能無法立即打印出來,因爲它被緩存且緩存未被「刷新」。 std::endl是一個換行符+沖洗從而部隊立即打印輸出:

std::cout << "Looking for segfault" << std::endl;