Cプログラミング:ワンセグ断層、printf、関連する癖
-
13-09-2019 - |
質問
多くの若手プログラマー、その有用性を挿入した数多くのprint-to-コンソールの表明"here1,""here2という風になるポイントコードを自分のプログラムはawry.この力デバッグ技術を保存しく、多くの時間が通っCS研究。しかし、始めたときにプログラミングC,Iヤーへの興味深い問題です。まったく行
void* test;
printf("hello world");
test[5] = 234;
のコースを取得しまsegfaultしないmalloc'ingメモリtestChar.しかし、論理的思考と"こんにちは世界"が印刷される前にワンセグ故障が起こり、その流れをコードすが、私の経験もある場合にはワンセグ故障が起こり、"こんにちは世界"はプロンプトが表示されます。(する事が出来なかった試験を経済的指標のみならず、がってこのような状況のも多く使用されるlinuxボックス) 私はこの推測していずれかのコンパイラの整理もおよび/またはprintfを使うバッファのフラッシュされ非同期状態を考慮する必要があきます。これは全くの思惑は自分が正直にいかな印象を持ちます。その他の言語を利用していなどの問題を"testChar=..."の行には、"こんにちは世界"が印刷され、このように思決定の問題です。
私の質問は、あらかじめご了承くださいきっ。なぜなこんにちは世界を印刷しょうか。次に、より良いCプログラミングのデバッグ技法によりこれを確実に遂行するのと同じ基本的なこんなことをしたのだろう。し、簡単-直感的に、ラインのコードで問題なのか。
編集:った作例における事故によるハハ。私が今必要があるでsegfault.まぁ、どのよう常時 な いsegfaultを取得し、現在実際にも付いていて設備も良かった私法コード!
解決
このコードだ投稿は完全に法的な原因でsegfault-する必要がないmallocものです。問題な嘘かも-てください最小の例のコードの一因とされる問題です。
編集: おめでとうございます編集中のコードによって異なります。まだ、その理由は、"こんにちは世界"が表示されていないので、出力バッファれていないフラッシュされます。みaddinig
fflush( stdout );
後のprintf.
に関する位置にいくの選択肢:
- ョッピンprintfsを通じてコードを使用
__FILE__
や__LINE__
Cマクロ - 学習用デバッガがプラットフォームでのサポートのコアダンプを使用でき、コアる画像を探するエラーです。
他のヒント
printf
書き込み、標準出力に出力し、バッファ.あるバッファがないフラッシュされる前にプログラムがクラッシュできないの出力に出力します。つこれを避けるために:
- 使用
fprintf( stderr, "error string" );
以来、stderrはバッファ. - 追加の呼び出し
fflush( stdout );
後のprintfます。
としてのNeilており、その他の言われたが、コードを記述です。るまでの変更のバッファ testChar
ポイントです。
「簡単/直感的な方法、同様に問題となっているコードの行を見つけるには?」
の使用GDB(または任意の他のデバッガ)。の
あなたは-g
オプションでコンパイルどこプログラムワンセグ障害を見つけるために(デバッグシンボルが含まれるように)の GDB のからアプリケーションを実行し、それはワンセグ断層の上に停止します。
あなたは、あなたはワンセグ障害を持って、その時点で見ることがbt
コマンドでバックトレースで見ることができます。
例:
> gdb ./x
(gdb) r
Starting program: /proj/cpp/arr/x
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0x00000000
0x000019a9 in willfail () at main.cpp:22
22 *a = 3;
(gdb) bt
#0 0x000019a9 in willfail () at main.cpp:22
#1 0x00001e32 in main () at main.cpp:49
(gdb)
出力はデフォルトでバッファリングされた出力が実際にstdoutに書き込まれる前に、セグメンテーションフォルトが発生します。試してみてください。
fprintf(stderr, "hello, world\n");
(標準エラー出力はデフォルトでバッファリングされていない。)
このコードは、セグメンテーションフォールトべきではありません。あなただけのポインタ変数にリテラル文字列へのポインタを代入しています。あなたは、例えばだったら物事は異なるだろう無効なポインタでものをコピーするstrcpy
を使用します。
表示されないメッセージが原因バッファードI / Oとすることができます。改行文字\n
を印刷したり、出力バッファをフラッシュするfflush
を呼び出します。
次の2つの問題を抱えています。最初は、あなた(オリジナル)コードがセグメンテーションフォールトではないということです。これは、char型のポインタへの定数その文字列を割り当てるために完全に有効です。しかし、今のところわき残しておきましょう、あなたはをそこに何かを入れていたふりだろうのセグメンテーションフォルトます。
そして、それは通常のバッファの問題で、Cランタイムライブラリに1つ、OS自体で一つです。あなたはそれらをフラッシュする必要があります。
これを実行する最も簡単な方法は、(、UNIXでのLinuxでfsync
について完全に一定ではないが、あなたはシステム自体がダウンしない限り、これが最終的に起こるウィルことが保証されなければならない)であった。
printf ("DEBUG point 72\n"); fflush (stdout); fsync (fileno (stdout));
stdoutが端末かでない場合は、便利な、私はUNIXで、多くの場合、これをやったし、それは、Cランタイムライブラリは、UNIX(fflush
)にフラッシュされることを保証し、UNIXのバッファはディスク(fsync
)にsync'edされています「別のファイルハンドルのためにそれをやって直します。
void* test;
printf("hello world");
test[5] = 234;
の「Hello World」はどこか、システムによってバッファリングされていると、すぐに画面に表示されていないこと、その可能性が高いです。そのどんなプロセス/スレッド/何でも画面の書き込みを担当していることは、それを処理する機会を持つことができるためのチャンスを待って保存。そして、その待機(そしておそらく出力に他のデータをバッファリング)あなたが機能しているが、仕上げられています。これは、不正アクセスやセグメンテーションフォールトの上に来ています。