C ++プログラムでランタイムチェックの失敗#0が発生する-ESPの値が関数全体で適切に保存されませんでした...



C Program Encounters Run Time Check Failure 0 Value Esp Was Not Properly Saved Across Functio



今日、アクセス違反のクラッシュが発生しましたが、クラッシュコールスタックがそれ以上の手がかりを見つけられなかったため、デバッグモードで再度実行すると、次のようなデバッグエラーメッセージボックスが表示されました。

runtimecheckfailureESP



これの理由は何ですか?このエラーを再現するための簡単な例を見てみましょう。

BaseAとBaseBの2つの親クラスがあるとします。 BaseAとBaseBから継承するサブクラスChildがあります。



 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
class BaseA { public: virtual void foo()=0 } class BaseB { public: virtual void bar(int a)=0 } class Child: public BaseA, public BaseB { public: void foo() { cout<<'i'm foo in Child!'<void bar(int a) { cout<<'i'm bar in Child!'<

次の主な機能があるとします。

 1 2 3 4 5 6 7 8 9 10
int main() { BaseB* b = new Child() BaseA* a = (BaseA*)b BaseA* a2 = dynamic_cast (b) // This is actually calling bar(), // and will cause Runtime check failure about ESP if the foo and bar have different signature. a->foo() a2->foo() }

このメイン関数では、aはC-Styleによって変換され、a2はdynamic_castによって変換されます。このプログラムを実行すると、リリース時にアクセス違反のクラッシュが報告され、上記のESPエラーダイアログボックスがデバッグ中に表示されます。

関数の出力を以下に示します。



espoutput

これは、fooを呼び出したいが、実際にはbarを呼び出しているため、このESPエラーが間違っている理由を説明できますが、fooとbarの関数シグネチャが同じではないため、デバッグバージョンでESPのエラーメッセージが表示されます。ただし、bar(int a)のパラメーターを削除するように追加すると、fooとbarの関数シグネチャが同じになり、デバッグバージョンではこのESPプロンプトが表示されず、リリースモードまたはデバッグモードではエラーは報告されませんが、実行時に間違った関数を呼び出しました! ! !

下の画像を見て、vtableが何であるかを思い出してください:)

画像

参照することもできます C ++オブジェクトのメモリ構造を確認する方法とC ++の名前マングリングを復号化する方法-データベースとSQLのブログ記事 C ++オブジェクトのメモリ構造を見てください。

ESPエラーについては、stackoverflowで次の問題を参照できます。 c ++-ランタイムチェックの失敗#0-ESPの値が関数呼び出し全体で適切に保存されなかった-スタックオーバーフロー

転載:https://www.cnblogs.com/fresky/p/3314588.html