忘れられない激○○料理

はじめまして。詳しい方がいたらご教授頂きたいのですが。

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
です。

どなたか詳しい方、ご協力お願い致します!!

A 回答 (7件)

> 間接的に呼び出す場合はコンパイルできますね。


> まあ、こういうケースは経験したことがなかったので候補に挙げませんでした。

ありゃま。。専門家(笑)じゃ、コンパイラのバグでもないということかな。。まっ、どっちゃでもいいか^^;
    • good
    • 1
この回答へのお礼

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

ですが試しに純粋仮想関数をなくしてみた(空実装させた)ところ、Abortは発生しなくなりました。

明確な理由は分からないままですが、とりあえず解決させることができそうです。

ありがとうございました。

お礼日時:2007/09/13 07:18

てか、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 さんもエラーの出た実際のコードで、純粋仮想関数が呼び出されるようなことはないか、一度、コードを読んで確認されるのがいいかと思いますよ^^
    • good
    • 0

> では、No.1 のサンプルは g++ v.4.1.1 でコンパイル・リンクできるので、コンパイラのバグなんでしょうね(笑)勉強になりました。



間接的に呼び出す場合はコンパイルできますね。
まあ、こういうケースは経験したことがなかったので候補に挙げませんでした。
    • good
    • 0
この回答へのお礼

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

お礼日時:2007/09/13 07:21

> コンストラクタやデストラクタで純粋仮想関数を呼び出すコードを書くとエラーになるので…



あっ、そうなんですか^^
では、No.1 のサンプルは g++ v.4.1.1 でコンパイル・リンクできるので、コンパイラのバグなんでしょうね(笑)勉強になりました。
    • good
    • 0

コンストラクタやデストラクタで純粋仮想関数を呼び出すコードを書くとエラーになるので、たぶん違うかと思います。



このメッセージは、

1. おかしなポインタを用いてメンバ関数を実行しようとした。
2. スタック破壊などが発生し、すでにプログラムが破綻している。
3. コンパイラの最適化バグ

の場合に見た記憶があります。
    • good
    • 0

あぁ、デストラクタのユーザコードが実行される前に、仮想テーブルが置き換わるので、~A() の中の g() 内から呼ばれる f() は B::f() ではなく、A::f() が呼ばれるんだと思います。

純粋仮想関数はなんらかのチェックをすり抜けて呼び出された場合を考慮して、abort() を呼び出すようになってるんだと思います。
    • good
    • 0

abort() :

http://www.linux.or.jp/JM/html/LDP_man-pages/man …

消滅時というから、デストラクタの中で、純粋仮想関数を呼び出しているとかじゃないんですかね?以下のようなことをしているとエラーになりますけどね^^ これとは、違う原因かな??

====
#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)
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


おすすめ情報