私は 3rd-Pary ライブラリの巨大なクラスを使用しています。関連するものの抜粋を次に示します。
class SomeClass {
// ...
public:
// ...
virtual int SetTableSize(unsigned int uiTableID, int iSize);
// ...
protected:
// ...
virtual int Set_0xB0_0x23_IsoTableData(unsigned char* ucData, int iLen);
// ...
};
アプリケーションがメモリ アクセス違反で壊れます。コール スタックの一番上の項目は の実装のコード行でSet_0xB0_0x23_IsoTableData
、2 番目の項目は次のようなコード行です。
someClassInstance.SetTableSize(2, 400);
デバッグ ビューでucData
は、値0x00000002
が であるため、実際には の実装を呼び出す代わりにSetTableSize
、コードに従って発生する必要があるように見えSet_0xB0_0x23_IsoTableData
ますが、指定されたパラメーターで呼び出されます。ポインターが有効でないため、明らかにエラーが発生します。
ここで何が起こるかを理解するために、私はすでに多くの時間を費やしてきました。Linux で GCC を使用して別のアプリケーション内で同じコードをコンパイルすると、そこで動作します。これは Visual Studio コンパイラのバグですか? このコードをコンパイルしても、警告は表示されません。
バグを再現するための最小限の作業例を作成することはできません-少なくとも、これが発生する理由を理解するまでは. SomeClass
ヘッダーにはかなりの数#ifdef
の s が含まれているため、最初に思ったのは、プリプロセッサの定義はSomeClass
、呼び出し元のコードをコンパイルするときと、含まれているモジュールをコンパイルするときでは異なるということでした。ただし、再確認したところ、定義は同じです。
だから私が聞きたいのは基本的に:
- 仮想メソッドの呼び出しが別の仮想メソッドの実装を呼び出すことができる条件は? (これは継承に関するものではありません。2 つのメソッドは同じクラスで定義されており、シグネチャを共有しておらず、可視性も異なります)
- このようなエラーをデバッグするにはどうすればよいですか? クラス インスタンスのディスパッチ ベクターを Visual Studio で表示することはできますか?