• ベストアンサー

C++でアボート(Abort)で処理が強制終了してしまう

はじめまして。詳しい方がいたらご教授頂きたいのですが。 C++で書いたコードをビルドしてLinuxでの実行したところ Abortが発生して困っています。 マルチスレッドを使用するようなコードで、あるインスタンス消滅時にアボートが発生して終了します・・・。 (1)アボートってなぜ出るのでしょうか? (2)以下のエラーが出ますが、原因は何か分かりません。 ------------------------------------- pure virtual method called terminate called without an active exception Aborted ------------------------------------- 環境は、 SUSE Linux v10.0 g++ (GCC) 4.0.2 20050901 GNU Make 3.80 です。 どなたか詳しい方、ご協力お願い致します!!

質問者が選んだベストアンサー

  • ベストアンサー
  • mikaemi
  • ベストアンサー率50% (33/65)
回答No.7

> 間接的に呼び出す場合はコンパイルできますね。 > まあ、こういうケースは経験したことがなかったので候補に挙げませんでした。 ありゃま。。専門家(笑)じゃ、コンパイラのバグでもないということかな。。まっ、どっちゃでもいいか^^;

goopon
質問者

お礼

ご親切に回答ありがとうございます。 > サンプルをコンパイル・リンクして実行したら、同じようなメッセージが > 出ますし(笑)goopon さんもエラーの出た実際のコードで、純粋仮想関 > 数が呼び出されるようなことはないか、一度、コードを読んで確認される > のがいいかと思いますよ^^ アドバイスをもとにコード見直しました。 確かに純粋仮想関数はあるものの、特に基底クラスで呼び出すようなまずいコーディングはしていません。 ですが試しに純粋仮想関数をなくしてみた(空実装させた)ところ、Abortは発生しなくなりました。 明確な理由は分からないままですが、とりあえず解決させることができそうです。 ありがとうございました。

その他の回答 (6)

  • mikaemi
  • ベストアンサー率50% (33/65)
回答No.6

てか、g++ v.4.1.1 が賢くないコンパイラだということかな^^ Stroustrup の『C++の設計と進化』初版 ソフトバンクのp.359 に ==  …  public:  virtual void f() = 0;  void g();  A(); }; A::A() {  f(); // エラー: 純粋仮想関数が呼ばれた  g(); // これは無害のようだ } A::f() の不法な呼び出しは、コンパイラが容易に補足できる。しかし A::g() はほかの翻訳単位の中でこんな定義かもしれない:  void A::g() { f(); } その場合は、複数のコンパイル単位にわたって分析するコンパイルでなければエラーを検出できない。代わりにランタイムエラーをだすことになるだろう。 == とありますが、今は、検出できないと標準準拠じゃないコンパイラになるということですね。 しかし、仮にコンパイラのバグだとしても goopon さんの場合は、g++ のようなので、純粋仮想関数の呼び出しをしてるんじゃないでしょうかね^^ サンプルをコンパイル・リンクして実行したら、同じようなメッセージが出ますし(笑)goopon さんもエラーの出た実際のコードで、純粋仮想関数が呼び出されるようなことはないか、一度、コードを読んで確認されるのがいいかと思いますよ^^

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.5

> では、No.1 のサンプルは g++ v.4.1.1 でコンパイル・リンクできるので、コンパイラのバグなんでしょうね(笑)勉強になりました。 間接的に呼び出す場合はコンパイルできますね。 まあ、こういうケースは経験したことがなかったので候補に挙げませんでした。

goopon
質問者

お礼

回答ありがとうございます。 そうですね。間接的にであればコンパイルとおりそうですね。 ですが、そのようなコーディングではないのですが・・・。

  • mikaemi
  • ベストアンサー率50% (33/65)
回答No.4

> コンストラクタやデストラクタで純粋仮想関数を呼び出すコードを書くとエラーになるので… あっ、そうなんですか^^ では、No.1 のサンプルは g++ v.4.1.1 でコンパイル・リンクできるので、コンパイラのバグなんでしょうね(笑)勉強になりました。

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.3

コンストラクタやデストラクタで純粋仮想関数を呼び出すコードを書くとエラーになるので、たぶん違うかと思います。 このメッセージは、 1. おかしなポインタを用いてメンバ関数を実行しようとした。 2. スタック破壊などが発生し、すでにプログラムが破綻している。 3. コンパイラの最適化バグ の場合に見た記憶があります。

  • mikaemi
  • ベストアンサー率50% (33/65)
回答No.2

あぁ、デストラクタのユーザコードが実行される前に、仮想テーブルが置き換わるので、~A() の中の g() 内から呼ばれる f() は B::f() ではなく、A::f() が呼ばれるんだと思います。純粋仮想関数はなんらかのチェックをすり抜けて呼び出された場合を考慮して、abort() を呼び出すようになってるんだと思います。

  • mikaemi
  • ベストアンサー率50% (33/65)
回答No.1

abort() : http://www.linux.or.jp/JM/html/LDP_man-pages/man3/abort.3.html 消滅時というから、デストラクタの中で、純粋仮想関数を呼び出しているとかじゃないんですかね?以下のようなことをしているとエラーになりますけどね^^ これとは、違う原因かな?? ==== #include <iostream> struct A { virtual void f() = 0; virtual void g() { f(); } ~A() { g(); } }; struct B : A { void f() { std::cout << "B::f()\n"; } }; int main() { B b; } ===== $ ./a.exe pure virtual method called terminate called without an active exception Aborted (core dumped)

関連するQ&A