Runtime Check Error # 0 - ESP value was not properly stored during function call

I created a simple program that demonstrates the runtime error that I get with my Qt application that uses multiple inheritance. The inheritance tree is as follows:

QGraphicsItem (abstract) \ QGraphicsLineItem MyInterface (abstract) \ / \ / MySubclass 

And here is the code:

 /* main.cpp */ #include <QApplication> #include <QGraphicsScene> #include <QGraphicsLineItem> //simple interface with one pure virtual method class MyInterface { public: virtual void myVirtualMethod() = 0; }; //Multiple inheritance subclass, simply overrides the interface method class MySubclass: public QGraphicsLineItem, public MyInterface { public: virtual void myVirtualMethod() { } }; int main(int argc, char** argv) { QApplication app(argc, argv); //init QApplication QGraphicsScene *scene = new QGraphicsScene(); //create scene scene->addItem(new MySubclass()); // add my subclass to the scene Q_FOREACH(QGraphicsItem *item, scene->items()) // should only have one item { MyInterface *mInterface = (MyInterface*)item; // cast as MyInterface mInterface->myVirtualMethod(); // <-- this causes the error } return 0; } 

Debugging in visual studio results in a runtime error when invoking an interface method:

  Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention. 

Any idea what the problem is?

+7
source share
2 answers

Since you are using multiple inheritance, the vftable pointer to what MyInterface* is actually a pointer to the QGraphicsLineItem vftable .

A dynamic_cast will solve the problem because it will return the correct vftable

 MyInterface* mInterface = dynamic_cast<MyInterface*>(item); 

A simple example:

 class A { public: virtual void foo() = 0; }; class B { public: virtual void goo() {}; }; class C : public B, public A { public: virtual void foo() {}; }; //.... B* c = new C; // c is at 0x00a97c78 A* a = (A*)c; // a is at 0x00a97c78 (vftable pointer of B) A* a1 = dynamic_cast<A*>(c); // a1 is at 0x00a97c7c (vftable pointer of A) 
+8
source

You will be fixed if you use dynamic listing.

 MyInterface* mInterface = dynamic_cast<MyInterface*>(item); 

This question discusses various C ++ techniques and when to use them. In your case, because of multiple inheritance, you should use dynamic casts

+1
source

All Articles