0

The snippet below will coredumped in fun() method. Why calling c->b.f() works in main() but failed in the function call?

class A {
 public:
  inline virtual void f() const {printf("A\n");}
};

class B : public A {
 public:
  inline void f() const override {printf("B\n");}
};

class C {
 public:
  B b;
};

void fun(const B &b) {
  b.f();                         // coredump
}

int main() {
  C *c = (C*)malloc(sizeof(C));
  c->b.f();                      // print "B"
  fun(c->b);
  return 0;
}

I guess it's because the virtual table is not initialized properly.

brayden
  • 3
  • 1
  • `*c` is uninitialized memory after the malloc. Objects need to be properly constructed. – sp2danny Nov 29 '22 at 13:27
  • Malloc here just allocating some memory, but not calling the constructor, you need to call constructors explicitly after memory initialization. Put this line after memory allocation to call constructor of C. ```new (c) C();``` – Vishal Nov 29 '22 at 15:03

1 Answers1

0

You are allocating memory for class C using malloc, but this doesn't create any object of class C. your program don't have any valid object and have undefined behavior.

As it is undefined behavior, your program may fail or may not be at c->b.f();

If you really want to use malloc, you should use placement new in your program to create object of your class.

C *c = (C*)malloc(sizeof(C));
new (c) C();

And to destroy your object and free the allocated memory, you should do

c->~C();
free(c);
Vishal
  • 516
  • 5
  • 9