0

Cコードを介して純粋仮想基本クラスポインタを として渡していvoid *ます。

C++ で基本クラスを逆参照すると、デバッガーはそのすべてのメンバーにアクセスできます。ただし、純粋仮想関数にアクセスしようとすると、SEGFAULT/アクセス違反が発生します。「0xc でメモリにアクセスできません」というメッセージがデバッガーに表示されます (純粋な仮想関数にアクセスしようとすると)。

コンストラクターが戻る前に関数が呼び出されている可能性がありますが、これは問題になりますか? 他に何を探すべきですか?他のすべての変数は無傷のようです。

コード:

the_socket_base* thisptr = reinterpret_cast<the_socket_base*>(watcher->data);  
thisptr->CallPureVirtualFunction();  
delete thisptr;
thisptr->CallSecondPureVirtualFunction();  //OOPS! It crashed
...  
watcher->data = this; // Associate socket with the watcher (Where 'this' is the base class)  
// NOTE THAT THE ABOVE ALWAYS HAPPENS IN THE CONSTRUCTOR

更新: コードは部分的に機能しており、オブジェクトが削除された可能性があります。読み取りハンドラー (それ自体を削除できます) を実行してから、チェックせずに書き込みハンドラーを実行するため...おそらくそれが原因です。


答え

最終更新: Keith のコメントが正しかったことを明確にしたいと思います。オブジェクトを削除していて、削除後にアクセスしようとしました。非常に単純な間違い!delete this;トリッキーな落とし穴です。すべてのコメントをありがとう。

4

2 に答える 2

2

コードがなければ、言うのは難しいです。2 つの可能性 OTOH:

  • コンストラクタまたはデストラクタから直接または間接的に仮想関数を呼び出しています-それはできません。
  • 多重継承を使用しています - void * ブレークを介したキャスト
于 2011-04-05T06:13:37.650 に答える
0
delete this; // Is dangerous, use with care

私がしていたことは、これを削除することです。純粋仮想関数で、すぐに戻り、既に削除されたオブジェクトで別の純粋仮想関数を呼び出します。

  • オブジェクトがすでに削除されている場合、純粋な仮想 vtable は失敗します
于 2011-04-05T07:14:57.360 に答える