ファイル内の各単語の数を数えようとしています。ファイルは、stdin またはコマンド ラインで指定されたファイル名 (./count -f filename) のいずれかです。これまでのところ、コマンドラインからファイルを読み取るときに、プログラムは正しい出力を提供します。しかし、標準入力から読み込もうとするとエラーが発生します。プログラムは最初に正しい結果を出力し、次にセグメンテーション エラー (コア ダンプ) を返します。興味深いことに、このプログラムは私の Mac では動作しますが、Linux では動作しません。
1 に答える
よし、魚をあげる代わりに、魚の釣り方を教えよう...
表示された場合segmentation fault
は、オペレーティング システムがメモリ アクセス エラーを検出したことを意味します。これは通常、ポインターを操作するときに C/C++ で発生します。ポインターは非常に危険であり、慎重に扱う必要があります。
問題が発生した場所を検出する方法は?
Linux は、プログラムが受け取ったときにあまり有益ではありませんSEGFAULT
が、多くの情報を提供します。あなたはそれを「読む」方法を知る必要があるだけです。
コアダンプは、セグメンテーション エラーが発生した時点のメモリ、スタック、および変数の画像です。それを実行する
gdb myapp core
ここで、myapp はアプリケーションの実行可能ファイルであり、core はコアダンプです。次のようなものが表示されます。
GNU gdb 19991004
Copyright 1998 Free Software ���.�
Core was generated by `testit'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /usr/lib/libstdc++-libc6.1-1.so.2...done.
Reading symbols from /lib/libm.so.6...done.
Reading symbols from /lib/libc.so.6...done.
Reading symbols from /lib/ld-linux.so.2...done.
#0 0x823221a in main () at blabla.c:3
10 *i++;
障害の原因となった行が正確に表示されます。その行にたどり着いた方法を正確に知りたい場合は、bt
これを入力すると、関数に渡されたパラメーターを含む、アプリケーションの main() から実際の障害までのバックトレースが表示されます。
セグメンテーション違反が発生した場所を正確に把握できれば、問題を解決するのははるかに簡単になると思います。
いくつかのメモ:
コアダンプが作成されていない場合。コンソールに次のように入力します。
ulimit -c unlimited
gdb で意味のあるシンボル名を有効にするには、プログラムを -g でコンパイルする必要があります。