"Strange" Seg Faults

Bugs involving pointers and memory can be some of the most challenging to find.

Example

The student says, "My code runs fine on my computer, but seg faults on linux1. It's really weird though, because I have this variable called fracSum that I ended up not using. If I leave its declaration in the program, the program runs, but when I compile I get a warning about having an unused variable (-5 points). If I take the declaration out, my program seg faults. I just don't get it."

If your program seg faults on any UNIX system, then your code is buggy !!! It is never the compiler that's at fault. It's always your code.

Here is the code :

int i, terms; FRACTION fracSum; NODEPTR head, temp; terms = 5; for(i = 1; i <= terms; i++) { temp = CreateNode(); GetData(temp, i); Insert(&head, temp); } . . . Since the program did not seg fault if the declaration was left in, I just added a call to PrintList after the list was built. This is what we saw: 301525671 203418536/393473027 1 0/1 0 1/-3 0 1/5 . . . The first node of the list had a fraction that was filled with garbage, but then the list was being formed fine. Why ?

Because head was not NULL when we began the list. head held an address that was okay for us to use, which contained some garbage. Since we were always inserting at the end of the list, our list building just continued from there.

Could we have used a debugger to find this error. Sure. Just inspect all of the values of the variables, including the pointers. We'd have seen right away that head was not NULL, 0.

What was going on with the variable fracSum ? Here's a picture of what the memory might have looked like that held main's variables (values shown in hex).

i terms fracSum head temp
0001 0005 11F8EAA700506AB7 FE0C 0DC4

With fracSum declared, head contains a garbage value that just happens to be an address that we are allowed to access. Even though there is no seg fault, our list has garbage in it.

i terms head temp
0001 0005 11F8 EAA7

With the declaration of fracSum removed, head contains a garbage value that happens to be an address that we are not allowed to access, so we get a segmentation fault.

Memory Problems

Whenever you have a situation where your program seg faults sometimes, then you know there is some kind of memory or pointer problem.

I've seen programs that seg fault, but after adding a printf statement as a probe, the program runs. Removing the printf statement causes it to dump again. Changes that you make to your program can cause your variables to be stored at different addresses than before, hence containing different garbage.