Where Do "Pure Virtual Function Call" Crashes Come From

Where do pure virtual function call crashes come from?

They can result if you try to make a virtual function call from a constructor or destructor. Since you can't make a virtual function call from a constructor or destructor (the derived class object hasn't been constructed or has already been destroyed), it calls the base class version, which in the case of a pure virtual function, doesn't exist.

class Base
{
public:
Base() { reallyDoIt(); }
void reallyDoIt() { doIt(); } // DON'T DO THIS
virtual void doIt() = 0;
};

class Derived : public Base
{
void doIt() {}
};

int main(void)
{
Derived d; // This will cause "pure virtual function call" error
}

See also Raymond Chen's 2 articles on the subject

C++ pure virtual function call doesn't throw run-time exception?

You are not getting the "pure virtual method call" exception because A::f() is not being called.

A1's constructor is calling its own A1::f() method, which is perfectly safe to do during A1's construction.

The issue with calling a virtual method in a constructor has to do with a base class constructor calling a derived class method, which doesn't work since the derived portion of the object being constructed doesn't exist yet.

So, to get the exception you want, you need to call f() in A's constructor rather than in A1's constructor.

windows application crashing with pure virtual function call

As was pointed out already, it is very unlikely that this is a build error. I had a quite complex project with a similar problem and was able to track it down by using _set_purecall_handler and providing my own handler. This way I was able to break into the debugger when it happened and see the call stack. Obviously an alternative here is to create the minidump when it happens. Remember that you need to prepare everything for the minidump before the program encounters an exception.

However, there is also a good chance this could be caused by a heap corruption. In such a case I would expect a variety of symptoms, though. You describe this specific symptom, so it's likely that your code is indeed at fault.

The project I mentioned above was a legacy project that modeled something similar to COM and there were indeed places where the compiler could not have possibly found all occasions of pure virtual functions for which no implementation existed in derived classes.

Crashing on calling virtual methods

The base class does implement the function, it just implements it wrong. It is not related to vtables or anything sophisticated. Solution 4 preferred (since it prevents building wrong programs), if not possible/desired 1 or 2 in that order.

Note that the error is not at all related to virtual functions, or inheritance in general (you do not use Bar, did you notice?). It is not even related to classes at all but would happen with any freestanding function as well. Consider:

#include <iostream>
#include <string>

// Note: UB -- nothing returned
int getInt() {}
std::string getStr() {}

int main(int argc, char ** argv)
{
// This probably works (read access from an arbitrary
// location on the stack which is in the prog's address space)
std::cout << getInt() << std::endl;

// This will crash. operator<< will try to access memory through
// a pointer value which is some arbitrary byte pattern on the stack.
// Probably not in the prog's address space.
// Then the destructor for the temporary string will
// try to delete the same
// memory which will crash in any case, even if it happens to
// point to valid memory (which, alas, was never allocated).
std::cout << getStr();

std::cout << "Still alive?\n"; // never printed
std::cout.flush();

return 0;
}

In order to prevent the error from happening with your original code, just return a value. If you implement the function and don't throw or abort (which are the three alternatives), i.e. if you return, you must return a value:

#include <iostream>

class Foo
{
public:
virtual std::string myString() { return "test\n";}
};

class Bar : public Foo
{
public:
};

int main(int argc, char ** argv)
{
Foo * bar = new Foo();
std::cout << bar->myString();

return 0;
}

c++ : Crash Saying Pure virtual called

Your Base class destructor needs to be virtual, Since it is not this code invokes Undefined Behavior.

Reference:

C++03 standard: Section 5.3.5/3:

If the static type of the operand is different from its dynamic type, the static type shall be a base class of the operand’s dynamic type and the static type shall have a virtual destructor or the behavior is undefined.


When you call a virtual function through constructor/destructor the dynamic dispatch does not work as you expect it to.

The type of this in constructor/destructor is of the type of the class who's constructor/destructor is being executed. While you expect the dynamic dispatch to call overidden derived class method Derived::vfunc(), it ends up in a call to Base::vfunc() which does not have a definition and hence results in Undefined Behavior.

Reference:

C++03 Standard 10.4/6:

"Member functions can be called from a constructor (or destructor) of an abstract class; the effect of making a virtual call (10.3) to a pure virtual function directly or indirectly for the object being created (or destroyed) from such a constructor (or destructor) is undefined."

Pure virtual method called error and crash

After I found a mistake from my side and deleted the question, I decided to undelete and partially answer it. I am sure somebody else can benefit from this stupid mistake (when you have a deadline in 3 hours you do make mistakes).

I knew it was something obvious: actually the code which I wrote as:

cCOLLECT_STR_TOP_NODES_HELPER helper( searchStr, attribute, this );
pHelper = &helper;

in reality was:

{
cCOLLECT_STR_TOP_NODES_HELPER helper( searchStr, attribute, this );
pHelper = &helper;
}

so helper went out of scope...

The problem is, I did debugging. pHelper was pointing to something meaningful, at least
that's what it looked like. I am still not sure how exactly the crash happened, but the
reason is clear. When the pointed object went out of scope, it is probably UB.
Still, if somebody describes what internally happened, I'll accept the answer.

What can cause a pure virtual function call in C++?

"The most common error I've seen that causes this is calling a virtual function from a base class constructor or destructor."

When an object is constructed, the pointer to the virtual dispatch table is initially aimed at the highest superclass, and it's only updated as the intermediate classes complete construction. So, you can accidentally call the pure virtual implementation up until the point that a subclass - with its own overriding function implementation - completes construction. That might be the most-derived subclass, or anywhere in between.

It might happen if you follow a pointer to a partially constructed object (e.g. in a race condition due to async or threaded operations).

If a compiler has reason to think it knows the real type to which a pointer-to-base-class points, it may reasonably bypass the virtual dispatch. You might confuse it by doing something with undefined behaviour like a reinterpret cast.

During destruction, the virtual dispatch table should be reverted as derived classes are destroyed, so the pure virtual implementation may again be invoked.

After destruction, continued use of the object via "dangling" pointers or references may invoke the pure virtual function, but there's no defined behaviour in such situations.

Suppress Pure Virtual Function call modal dialog and crash silently

Use the _set_purecall_handler function in your main application. It affects all the dlls loaded (directly or indirectly) by your application. MSDN says it should be callable via P/Invoke; this question addresses some possible issues. (Basically, the problem is that you have to do this for a specific CRT version.)

How to resolve pure virtual method called

By the time your destructor is called, the destructor of inherited classes has already been called. Within constructors and destructors, the dynamic type of the object can effectively be considered to be the same as the static type. That is, when you call virtual methods from within your constructors/destructors it's not the overriden versions of them that are called.

If SomePureVirtualMethod needs to be called at the destructor, then you will have to call it within the destructor of the class where the actual definition of the method you want is.



Related Topics



Leave a reply



Submit