Corrupted virtual table error

I came across what seems to me to be a damaged virtual table, which occurs as a result of creating and running the sample code presented below in Visual Studio 2015.

When I run it, an exception is thrown when assigning m_string.

I checked that the code builds and works as intended using the gcc and Clang compilers.

I tried to make the example as minimal as possible, as it was synthesized from a very large project.

In addition, I understand that I am returning null from some functions - the actual return value is not related to the problem, but there may be a return type. Is this a possible Visual Studio error?

#include <iostream> #include <memory> #include <string> struct A { virtual ~A(void) { } }; struct B { virtual ~B(void) { } }; struct C : public A, public B { virtual ~C(void) override { } }; struct D { virtual ~D(void) { } virtual B *func(void) = 0; }; struct E : public D { virtual ~E(void) override { } virtual C *func(void) override { return nullptr; } }; struct F : public A, public E { virtual ~F(void) override { } C *func(void) override { m_string = "Why does the act of setting this field cause a crash?"; return nullptr; } std::string m_string; }; int main(int argc, char **argv) { std::unique_ptr<F> pF(new F()); (dynamic_cast<D *>(pF.get()))->func(); pF->func(); return 0; } 
+5
source share
1 answer

The solution is to make inheritance from class A virtual.

 struct C : virtual public A, public B { virtual ~C(void) override { } }; 

or

 struct F : virtual public A, public E { ... } 

The problem is most likely related to virtual descriptors in the base classes. Perhaps others can provide more explanation why this works.

As @JamesAdkison pointed out, swapping inherited classes (changing struct C : public A, public B {...} to struct C : public B, public A {...} ) also fixes the problem; therefore, changes struct F : public A, public E { ... } to struct F : public E, public A { ... } . So this seems like an error in MSVC as mentioned by @Josh P.

+2
source

All Articles