C プログラムではprintf
、セグメンテーション違反の前のどこかに in コードがあると、出力されないことがあります。これはなぜですか?
6 に答える
からの出力printf()
がバッファリングされているためです。fflush(stdout);
の直後に追加するprintf
と、印刷されます。
また、これを行うこともできます:
fprintf(stderr, "error string");
stderr
バッファリングされていないためです。
関連する質問もあります。
printf の直後にセグメンテーション違反が発生し、出力バッファーがフラッシュされなかった場合、printf の効果は見られません。
ほとんどの libc 実装は、printf 出力をバッファーに入れます。通常、出力文字列に改行 (\n) を追加して、バッファの内容を強制的にフラッシュするだけで十分です。
printf の直後に出力バッファをフラッシュして、セグ フォールトの前に確実に発生するようにすることができます。例えば。フラッシュ(標準出力)
ランダムなヒント: セグメンテーション違反をデバッグしようとしている場合は、必ずvalgrindを試してください。それはそれをはるかに簡単にします!
出力ストリームのバッファリングを指摘する多くの回答が与えられました。
良くも悪くも、それが唯一の可能性にはほど遠い. セグメンテーション違反は、OS が何か間違ったことをしたことを検出したことを意味します。通常、割り当てられたメモリの外側に書き出されます。良くも悪くも (大抵はもっと悪いことですが) そのような状況でほとんどのことを行うと、少なくとも以前に問題が検出された時点/状況では、問題が検出されないようにするために、プログラムが内部的に行うことが十分に変更される可能性があります。
たとえば、以前に呼び出した関数がその値をスタック上の適切な場所に残したために、たまたま特定の値 (おそらくいくつかの小さな整数) を保持していた初期化されていないポインターを介して書き込みを行うことによって、セグメント フォールトが発生した可能性があります。後の関数が呼び出され、その同じ値をポインターとして使用したとき、(合理的に信頼できる) 書き込みが許可されていない場所として OS が検出した値が含まれていました。ただし、printf を呼び出すと、初期化せずに使用しているスタック上の場所にまったく異なる値が残ることになる場合があります。書いてはいけない場所にまだ書いていますが、書いてはいけないことをOS が認識していない場所にある可能性があります。