memory - In C++, why is `new` needed to dynamically create an object rather just allocation? -


i've got 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 use malloc allocate instance of derived, , try access polymorphic function x, program crashes (i 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 actual application lot more complex (it's sort of memory pool).


i'm pretty sure it's because of way allocate d: didn't use new.

i know of placement new operator, must need, i've never used , have got questions:

  • why application crashing, if don't use new?

    what new do?

    why can't use assignment operator assign value of derived( 123 ); memory area pointed d?

  • would need use new non-polymorphic types?

    how pod ones?

  • on c++faq linked above says memory region passed placement new must aligned object i'm creating.

    i know alignment is, don't know how check alignment needed class.

    malloc manual says:

    the malloc() , calloc() functions return pointer allocated memory suitably aligned kind of variable.

    and hope alignment needed class class size returned sizeof, address in form address_returned_by_malloc + * sizeof(my_class) suitable allocate objects.

    are hopes right?

let's go down line

  1. why application crashing, if don't use new?

virtual table corrupted.

the virtual table stuck right after allocated memory. when new class, generated code set vtable. however, malloc not initialize vtable

to see virtual table, run g++ -fdump-class-hierarchy

vtable derived derived::_ztv7derived: 3u entries 0     (int (*)(...))0 8     (int (*)(...))(& _zti7derived) 16    derived::x  class derived    size=16 align=8    base size=12 base align=8 derived (0x10209fc40) 0     vptr=((& derived::_ztv7derived) + 16u) <-- notice how part of structure   base (0x10209fcb0) 0 nearly-empty       primary-for derived (0x10209fc40) 

for similar reason, without overloading operator=, generated assembly code copy data , not vtable [again, compiler knows copy data, not vtable]

if want see pointer-based version valid vtable function:

derived e(123); d = &e; 
  1. would need use new non-polymorphic types?

if using virtual functions, yes, non-polymorphic types

  1. i hope alignment needed class class size returned sizeof, address in form address_returned_by_malloc + * sizeof(my_class) suitable allocate objects.

alignment not issue.


Comments

Popular posts from this blog

Delphi Wmi Query on a Remote Machine -