Search code examples
c++segmentation-faultvirtual-functions

Calling a virtual function using an object created on stack


I don't have much experience or knowledge of virtual functions, so the question may have an obvious answer. I am just trying to understand the reasoning.

I have a simple CTest class with two functions- func() and virtualFunc(). I am creating an object on the stack purely for testing purposes and want to observe its behaviour. I do realize we are supposed to create an object using new keyword on the heap, but I am interested in knowing the behaviour of a virtual function when the object is on the stack.

With the code that I have currently, it is resulting in a Seg Fault when I try to call the virtual function. Can anyone tell me why does virtual function result in a seg fault while the non-virtual function doesn't?

class CTest {
    public:
        void func() {
            printf("function was called.\n");
        }   
        virtual void virtualFunc() {
            printf("virtual function was called.\n");
        }   
};

int main (int argc, char ** argv) {
    CTest * obj = NULL;
    
    obj->func(); // this would print "function called" as what's inside the func()
    
    obj->virtualFunc(); 
    //line above results in segfault because C *obj is on stack; 
    //You would need to allocated obj on the heap for the virtual function to not Seg Fault.WHY?
    //by using "C*obj = new C", I am able to print the contents of virtualFunc() successfully.

}

Solution

  • CTest * obj = NULL;
    

    This is NOT how you create object on stack. This is how you create object pointer on stack and point it to nowhere.

    You can simply do:

    CTest obj; // This creates the object, calls constructor
    

    And since the object is treated like reference, not pointer, you can use

    obj.func();
    obj.virtualFunc();
    

    etc.

    To use pointer to stack variable, you can do:

    CTest obj_value; // This actually creates the object
    CTest * obj = &obj_value; // This creates pointer to stack object
    

    Whether the object is on stack or heap does not affect behavior of virtual functions.

    In your case, the fact that obj->func(); works and does not segfault is actually a bad luck. Methods are not stored inside the object. They are stored in code section of executable, once per whole program, not instance, just like regular functions. They are also translated to something like:

    CTest::func(CTest * this) // here this is obj
    

    And since this is invalid, but it is not used, nothing visibly wrong happens.

    In case of virtual functions, each virtual function call actualy reads this to get what is called vtable. This is where your program crashes, as this is null pointer.