2011-07-27 8 views
2

私はsegfaultをトリガする関数を呼び出すプロジェクトに取り組んでいます。私はこれを修正しましたが、処理中に次のことに気付きました。G ++コンパイラ:Segfaultの処理

私のコードの形式は、

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

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

「セグメンテーションフォルトを探して、」ラインSTDに印刷し、そして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の2回目の使用でバッファがオーバーフローし、オペレーティングシステムを呼び出してバッファを空にします。出力がバッファを離れたことを保証したい場合は、std::flushを使用する必要があります。行を終了し、バッファーをstd::endlでフラッシュすることができます。

+2

また、あなたは(おそらくエラーが報告の目的のために)バッファリングされていない 'のstd :: cerr'を、使用することができます。std::endlは改行+軍の即時プリントアウトようにフラッシュです。 –

+1

"\ n"の代わりに 'std :: endl'を指定しても、行が印刷されるという保証はありませんが、' std :: endl'では印刷される行のオッズがはるかに優れています。これがまだ機能しない2つの理由は、(1)他のバッファリングが行われている可能性があります。(2)SEGFAULTは、何らかの未定義の動作に対する応答です。未定義の動作については保証はありません。 –

+0

D'OH !!私は以前にストリームをフラッシュするためのendlを持っていましたが、デバッグの途中で削除されてしまいました。それを元に戻すのを忘れました。 – Alex

2

これはバッファリングと関係がある。 coutに書き込むものは、定期的にフラッシュされるだけの内部バッファに追加されます。ストリームにstd::flushを書き込むか、"\n"<< std::endlに置き換えると、バッファを明示的にフラッシュできます。

3

キャッシュされていて、キャッシュが "フラッシュされていない"ため、ラインがすぐに印刷されないことがあるためです。

std::cout << "Looking for segfault" << std::endl; 
関連する問題