I\'ve got this trivial class hierarchy:
class Base {
public:
virtual int x( ) const = 0;
};
class Derived : public Base {
int _x;
public:
Derive
Classes with virtual
members contain a pointer to a so-called vtable - basically a table of function pointers to the implementation of these virtual members. When you use operator new
, the constructor is called, which, even if it is an implicit constructor, will set up this pointer to the vtable properly.
However, malloc does not call the constructor. The vtable pointer is left uninitialized, point to some random memory. When you then attempt to call a virtual function, you dereference a bad pointer and crash (undefined behavior).
The solution is to use placement new to initialize the object before using it:
int main( ) {
Derived *d;
d = (Derived*) malloc( sizeof(Derived) );
new(d) Derived(123); // invoke constructor
// You could also do:
// new(d) Derived;
// *d = Derived( 123 );
std::cout << d->x() << std::endl; // crash
// Although in your case it does not matter, it's good to clean up after yourself by
// calling the destructor
d->~Derived();
return 0;
}
Some important things to note:
=
does not help. The default implementation of =
copies all member variables, but the vtable pointer is not a member and is not copied.