1

この男:

virtual phTreeClass* GetTreeClass() const { return (phTreeClass*)m_entity_class; }

呼び出されると、完全に再コンパイルした後でも、アクセス違反でプログラムがクラッシュしました。すべてのメンバー関数と仮想メンバー関数のメモリアドレスは正しいですが(デバッグモードのメソッドにマウスを合わせた)、この関数のメモリアドレスは0xfffffffcでした。

すべてが正常に見えました:'this'ポインター、そしてこの関数呼び出しまですべてが正常に機能します。この関数もかなり古く、私は長い間変更していませんでした。いくつかの作業の後で問題が突然発生しましたが、何が起こっているのかを確認するためにコメントしましたが、成功しませんでした。

だから私は仮想を削除し、コンパイルしました、そしてそれはうまくいきます。仮想を追加してコンパイルしましたが、それでも問題なく動作します。基本的に何も変更していませんが、以前に完全な再コンパイルを行ったのに、当時はまだエラーが発生していたことを覚えています。

問題を再現できませんでした。しかし今、それは戻ってきました。何も変更しませんでした。仮想を削除すると問題が修正されます。

4

3 に答える 3

2

自分が何をしているかを真剣に確信していない限り、ポリモーフィックタイプでCスタイルのキャストを使用しないでください。圧倒的な確率は、そうではなかったタイプにキャストすることです。ポインタが暗黙的にキャストされない場合(安全な基本クラスにキャストされるため)、間違っています。

于 2010-06-14T15:06:40.597 に答える
0

コンパイラとリンカは、他のソフトウェアと同様に人間が作成したソフトウェアであるため、本質的にエラーが発生しないようにすることはできません。

このような不可解な問題や修正に遭遇することもあります。ビルドが修正されたらncbファイルを削除するという神話がここにあります。

于 2010-06-14T14:52:08.207 に答える
0

再コンパイルすると元々問題が解決したので、最初に完全なクリーンアップと再構築を試してください。

それが失敗した場合、thisポインタが正しいように見えても、実際には削除/分解され、前にあった実際のオブジェクトのように見えるガベージメモリを指している可能性が非常に高くなります。gdbを使用してデバッグしている場合、オブジェクトのポインターの最初の単語はvtableになります。x/16xw <addr>その場所で(たとえば)メモリダンプを実行すると、gdbはそこにあるオブジェクトのvtableの種類を教えてくれます。それが最も親のタイプである場合、オブジェクトは間違いなくなくなっています。

あるいは、このポインタが毎回同じである場合は、という条件でクラスデストラクタにブレークポイントを設定できますthis == known_addr

于 2010-06-14T15:16:09.523 に答える