I’ve got this trivial class hierarchy:
class Base {
public:
virtual int x( ) const = 0;
};
class Derived : public Base {
int _x;
public:
Derived( int x ) : _x(x) { }
int x( ) const { return _x; }
};
If I use malloc to allocate an instance of Derived, and then try to access the polymorphic function x, program crashes (I get a segmentation fault):
int main( ) {
Derived *d;
d = (Derived*) malloc( sizeof(Derived) );
*d = Derived( 123 );
std::cout << d->x() << std::endl; // crash
return 0;
}
Of course my actual application is a lot more complex (it’s a sort of memory pool).
I’m pretty sure it’s because of the way I allocate d: I didn’t use new.
I know of placement new operator, which must be what I need, but I’ve never used it and have got some questions:
-
why is my application crashing, if I don’t use
new?What does
newactually do?Why can’t I just use the assignment operator to assign the value of
Derived( 123 );to the memory area pointed byd? -
Would I need to use
newalso for non-polymorphic types?How about POD ones?
-
On the C++Faq I linked above it says that the memory region passed to placement
newmust be aligned for the object I’m creating.I know what alignment is, but I don’t know how to check the alignment needed for my class.
mallocmanual says:The malloc() and calloc() functions return a pointer to the allocated memory that is suitably aligned for any kind of variable.
And I hope that the alignment needed for my class is the class size as returned by
sizeof, so that any address in the formaddress_returned_by_malloc + i * sizeof(my_class)is suitable to allocate my objects.Are my hopes right?
Let’s go down the line
Virtual table is corrupted.
The virtual table is stuck right after the allocated memory. when you
newa class, the generated code will properly set up the vtable. However, malloc will not properly initialize the vtableTo see the virtual table, run
g++ -fdump-class-hierarchy
For a similar reason, without overloading operator=, the generated assembly code will only copy the data and not the vtable [again, the compiler only knows to copy the data, not the vtable]
If you want to see a pointer-based version with a valid vtable function:
If you are using virtual functions, then yes, even for non-polymorphic types
Alignment is not an issue.