3
class CBase {
public:
    void print()
    {
        cout<<"In base print func\n";
    };
};

class CDerived: public CBase {
public:
    void print()
    {
        cout<<"In derived print func\n";
    };
};

int main()
{
    CBase b;
    CBase* pb;
    CDerived d;
    CDerived* pd;
    pd->print();
    return 0;
}

The above code runs fine but when i make the print function in class CBase as virtual it results into segmentation fault.

I think there is some basic logic behind this of which I am not aware. Please give your comments why this is so?

ildjarn
  • 62,044
  • 9
  • 127
  • 211
Kundan Kumar
  • 1,974
  • 7
  • 32
  • 54

1 Answers1

3
CDerived* pd;
pd->print();

Pointer is not initialized -> undefined behavior.

You need

CDerived* pd = new CDerived;
pd->print();

Also, it doesn't run fine. Or rather, you're unlucky that it runs fine. Virtual dispatch requires a virtual table, and since the pointer is not initialized, the virtual table pointer doesn't exist, that's why it crashes when the functions is virtual.

When it's not virtual, it's still undefined behavior, but it doesn't crash because it doesn't use any members.

To prove this, try the following:

class CBase {
public:
    int y;
    void print()
    {
        cout<<"In base print func\n" << y;
    };
};

class CDerived: public CBase {
public:
    int x;
    void print()
    {
        cout<<"In derived print func\n" << x;
    };
};

it will crash even if the functions is not virtual.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • @luchian..but when i dont make it virtual then it runs fine even without initializing the pointer. – Kundan Kumar May 09 '12 at 21:00
  • 1
    @KundanKumar I explained why. It runs as expected, but it's still undefined behavior. – Luchian Grigore May 09 '12 at 21:01
  • 2
    @Kundan : No, it only _appears_ to run fine. Undefined behavior is never correct. – ildjarn May 09 '12 at 21:01
  • @KundanKumar - it's still undefined behaviour which is bad. You're *unlucky* if it works in that case because undefined behaviour slipping through un-noticed is just storing a problem up for the future – Flexo May 09 '12 at 21:02
  • @KundanKumar See edited answer, I provided an example where it crashes even if the functions is not virtual. – Luchian Grigore May 09 '12 at 21:02
  • @LuchianGrigore...so it means that the virtual table is created when we create an object but not necessarily when a function is declared as virtual inside the class. – Kundan Kumar May 09 '12 at 21:04
  • @ildjarn - that's too black and white. There are indeed some technically undefined things that can be correct given intimate knowledge of the implementation. They are extreme cases, to be avoided, but never say never. – Edward Strange May 09 '12 at 21:04
  • @KundanKumar a virtual table is created on compilation. The pointer to the virtual table is created when you instantiate an object. – Luchian Grigore May 09 '12 at 21:04
  • @CrazyEddie : Working and being correct are two different things. (And do you really want to give the OP the impression that UB is _sometimes_ okay?) – ildjarn May 09 '12 at 21:08