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.
}
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.