virtual function and segmentation fault


A

asit

Look at the following code snippet..


#include <iostream>

using namespace std;

class ex
{
int i;
public:
ex(int ii=0):i(ii) {}

~ex() { cout<<"dest"<<endl; }

virtual void show()
{
cout<<"show fun called"<<endl;
}

};

int main()
{
ex *ob = NULL;
ob->show();
return 0;
}


The output here is segmentation fault.

If I make show non-virtual, there is no segmentation fault.

Can somebody explain me the reason ??
 
Ad

Advertisements

A

asit

Is only one virtual table created for a class or different tables are created for different classes ??
 
R

Richard Damon

Look at the following code snippet..


#include<iostream>

using namespace std;

class ex
{
int i;
public:
ex(int ii=0):i(ii) {}

~ex() { cout<<"dest"<<endl; }

virtual void show()
{
cout<<"show fun called"<<endl;
}

};

int main()
{
ex *ob = NULL;
ob->show();
return 0;
}


The output here is segmentation fault.

If I make show non-virtual, there is no segmentation fault.

Can somebody explain me the reason ??

When show() is virtual, in order to locate the function to call, the
code needs to access the "vtable" to find the address of the function,
and since the object pointer is NULL, this will fault.

When show() isn't virtual, the compiler generally doesn't need to look
at the object to call the function, and since your implementation of
show doesn't refer to any member variables, it MIGHT be able to run
without problems (but it still has invoked "Undefined behavior" (which
sometimes does what you want).
 
R

Richard Damon

Do you think that explaining the behaviour of particular undefined
behaviour invocations is useful? The advice should be to avoid undefined
behaviour, period. Explaining how things work (such as dynamic dispatch)
can be done without resorting to explaining it in terms of undefined
behaviour. :)

/Leigh

Yes I do. The OP obviously has tried both options and is puzzled by the
difference in behavior (not noticing that both were undefined behavior).
By pointing out how some undefined behavior typically operates, it does
a couple of thing.

One, it points out that just because something "works" doesn't mean you
haven't committed undefined behavior (note that my description of the
non-virtual case doesn't say it WILL work, just why it might).

Two, understand why some behaviors are defined as "undefined" helps give
reality to the concept. Things are not undefined behavior just because
the writers of the standard didn't want to define it, but there is
almost always a real reason why it is impractical to define the behavior
on all implementations. Knowing this, it makes it easier to remember
what is undefined behavior, as well as to understand code that might
invoke what is undefined behavior in the C++ standard but may be defined
by another standard or the implementation.

For example, the code:

int i;
i = 30000 + 30000;

has possibly invoked undefined behavior by possible overflowing signed
integer arithmetic (if ints are only 16 bits). Knowledge that you are on
a 32 bit machine, or that (as is common), the behavior of in integer
arithmetic is reasonably well defined on this platform, allows one to be
less paranoid in the checks that need to be made to avoid/detect problems.
 
Ad

Advertisements

M

Miles Bader

Leigh Johnston said:
Do you think that explaining the behaviour of particular undefined
behaviour invocations is useful?

Sure; concrete examples are often a very useful tool for understanding.

-miles
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top