views:

306

answers:

2

I am attempting to output functions common to a set of objects that share a base class and I am having some difficulty. When the objects are instantiated they are stored in an array and then I am attempting with the following code to execute functionality common to all the objects in this loop:

  if ( truck <= v ) // all types of trucks

vptr is an array of objects and the functions in the loop are common to all the objects. The code compiles fine but when I run it I get a segmentation fault when it enters this loop. I'm fairly confident that the call to the first function in this loop is what is causing the problem.

this is how I have instantiated the objects in a previous loop:

        vptr[ i ] = new Vehicle( sn, pc );

I should also mention, I'm sorry I forgot to be clear from the beginning, that in this array each object is of a different class. They all share a base class but they are derived objects of that class. Sorry for forgetting that probably important piece of information.

thanks nmr

+6  A: 

dynamic_cast to a pointer type returns a null pointer (aka 0, NULL) if the object isn't of the specified type. You must check the pointer before using it, or use a reference type (which throws an exception on failure instead):

if (Truck* p = dyanmic_cast<Truck*>(vptr[i])) {
  // use the pointer here
}
else {
  // vptr[i] doesn't point to a Truck
}

(Notice the nice effect of the correctly-typed pointer being scoped for you, take advantage of this when you can to improve readability.)

Roger Pate
+2  A: 

If you use a debugger, you can easily figure out which call is causing the segmentation fault and even examine memory to see if you have a null pointer, etc.

GCC with GDB is a good example. Try this--first build your application with debugging info (to do this you add the -g switch to your compiler):

gcc -g test.c -o myProgramName

Now launch GDB:

gdb myProgramName

At the first GDB prompt, enter the 'r' command to run the program:

(gdb) r

Then, when you reach the segfault, use the 'bt' command to view the stack trace and find out where the program was when it had the bad memory access:

Program received signal SIGSEGV, Segmentation fault.
0x08048380 in testFunction2 () at test.c:17
17      *test = 1;
(gdb) bt
#0  0x08048380 in testFunction2 () at test.c:17
#1  0x0804836e in testFunction1 () at test.c:10
#2  0x0804835a in main () at test.c:5

When you compile with debugging enabled, it lets you see the source file, line number, and the actual code that caused the crash. Learning to use a debugger makes hunting down segmentation faults really easy.

Debuggers also let you examine memory--with the above example, I can check the value of the 'test' pointer:

(gdb) print test
$1 = 0x0

Whoops, the pointer was NULL when I tried to change the memory it referenced, thus I was accessing memory my program wasn't allowed to touch, causing a segmentation fault.

Try the 'print' command with objects as well--GDB is smart enough to actually break the object down and show you the value of each of the object's members. Additionally, you can use the 'printf' command to print strings, etc. while you're debugging your program.

Hope this is helpful, Maha

Maha
We are supposed to work logged in to our schools server and use their development tools but I have not attempted to use gdb before but hopefully they have it because we use g++. Thanks for the tip.
nmr
This is what I got when using it:Program received signal SIGSEGV, Segmentation fault.0x000000000040358d in main ()
nmr
Did you compile with the -g option? g++ -g myapp.cpp
Maha
Then use the 'bt' command (backtrace) I mentioned above to look at the call stack; it shows you which functions were called to get you to where you are when the program segfaults.
Maha