Avoiding dereference of NULL pointer

T

Tony Jackson

Hi

I'm quite new to C programming - I have more of a Java background: maybe
someone here can advise me.

I'm nearly finishing a little program but it has some hard-to-find bugs
that basically lead to a couple pointers sometimes being NULL at the
wrong time. As it stands the program just bombs out when it tries to
dereference the NULL, which obviously isn't good (especially when it
happens with the customer looking on!!).

I don't think there's any serious problem to worry about, and what I'd
like to do is be able to ignore the dereference attempt and just carry
on - probably the next time round the loop the pointer will be OK. In
Java, I'd put a try block around the main loop, and if we catch an
exception then just jump back to the start of the main loop. What's the
corresponding thing in C?

Thanks!
 
P

pete

Tony said:
Hi

I'm quite new to C programming - I have more of a Java background: maybe
someone here can advise me.

I'm nearly finishing a little program but it has some hard-to-find bugs
that basically lead to a couple pointers sometimes being NULL at the
wrong time. As it stands the program just bombs out when it tries to
dereference the NULL, which obviously isn't good (especially when it
happens with the customer looking on!!).

I don't think there's any serious problem to worry about, and what I'd
like to do is be able to ignore the dereference attempt and just carry
on - probably the next time round the loop the pointer will be OK. In
Java, I'd put a try block around the main loop, and if we catch an
exception then just jump back to the start of the main loop.
What's the
corresponding thing in C?

Put code in place to prevent
the deference attempt of the null pointer, instead.
 
T

Tony Jackson

Put code in place to prevent
the deference attempt of the null pointer, instead.

Thanks for the reply. That would mean testing for NULL at every pointer
dereference which would be a lot of extra code - I was looking for a
catch-all solution. (Unfortunately I've already experienced several
different places where the program tries to dereference NULL, and who
knows how many others there are lurking in the background...)
 
J

jkohen

Hi
I'm nearly finishing a little program but it has some hard-to-find bugs
that basically lead to a couple pointers sometimes being NULL at the
wrong time. As it stands the program just bombs out when it tries to
dereference the NULL, which obviously isn't good (especially when it
happens with the customer looking on!!).

Use assertions to catch the NULL pointers that should never be null
(i.e. indicating broken program logic) during debugging, then fix your
code. Anything else is a bad hack.

As for pointers which may be null, just check for nullity by comparing
against the preprocessor macro NULL.
 
F

Flash Gordon

pete wrote, On 15/12/07 09:59:
Well, the program is not ready to put in front of a customer if you do
not understand *why* the pointers are null.

In that case I am glad that I am not your customer.

Or, as you seem to not understand what is going on, something else that
does not show up as easily might be wrong.
Put code in place to prevent
the deference attempt of the null pointer, instead.

Or better yet actually find out why it is null and fix the real cause.
 
S

santosh

Tony said:
Thanks for the reply. That would mean testing for NULL at every
pointer dereference which would be a lot of extra code - I was looking
for a catch-all solution. (Unfortunately I've already experienced
several different places where the program tries to dereference NULL,
and who knows how many others there are lurking in the background...)

A short while back Martin Ambuhl posted an illustration of handling a
SIGSEGV signal (which is what is likely to be delivered to your program
on a null pointer deference) and continuing. Be aware though that the C
standard explicitly says that the further behaviour of a program that
handles SIGSEGV is undefined, so anything may happen. Your
implementation may, however provide more guarantees.

Your comments indicate that the code is broken, to say the least. I'm
not sure about Java, but in C broken code generally leads to nasty
surprises. Consider handling SIGSEGV only if a better option (like
correcting the code in the first place) fails. Signal handling is
subtle and difficult to get right in C.
 
C

Chris Dollin

Tony said:
I'm quite new to C programming - I have more of a Java background: maybe
someone here can advise me.

I'm nearly finishing a little program but it has some hard-to-find bugs
that basically lead to a couple pointers sometimes being NULL at the
wrong time. As it stands the program just bombs out when it tries to
dereference the NULL, which obviously isn't good (especially when it
happens with the customer looking on!!).

I don't think there's any serious problem to worry about, and what I'd
like to do is be able to ignore the dereference attempt and just carry
on - probably the next time round the loop the pointer will be OK.

(and then he said)
In Java, I'd put a try block around the main loop, and if we catch an
exception then just jump back to the start of the main loop.

In Java, as in C, if our program dereferences a null, /it is an error/,
and the program should be fixed. Yes, it's nice that you can catch the
error in Java -- but you should /still/ work out /why/ some idiot code
is dereferencing null, and sort it out.

I've written a fair bit of Java, and blithely ignoring null pointer
exceptions wasn't part of /any/ of it.

Exception handling is for robustness, not wimping out. How on Earth
do you know the program's in a safe state if it's been arbitrarily
thrown out of by an NPE?
 
J

James Kuyper

Tony said:
Thanks for the reply. That would mean testing for NULL at every pointer
dereference which would be a lot of extra code - I was looking for a
catch-all solution. ...

Properly designed code automatically ensures that pointers are not null
when de-referenced; there's no need to insert large numbers of explicit
tests for NULL except during debugging, when you're trying to figure out
the way in which your code is improperly designed.

Your code is obviously not properly designed in this regard, and you
therefore DO need to debug it. I guarantee you that the kind of mistakes
that result in attempts to dereference null pointers will not be minor,
ignorable ones. Even if you could ignore such attempts, your program
will go ahead and NOT do what you intended it to do. Fix the problems
that cause such attempts to happen.
> ... (Unfortunately I've already experienced several
> different places where the program tries to dereference NULL, and who
> knows how many others there are lurking in the background...)

I would strongly recommend not using your program until you have found
enough time to find and fix all of the bugs that
 
M

Malcolm McLean

Chris Dollin said:
Exception handling is for robustness, not wimping out. How on Earth
do you know the program's in a safe state if it's been arbitrarily
thrown out of by an NPE?
The customer isn't necessarily very sophisticated. He wants to see a program
doing things on screen, so he's got confidence that the project is
progressing to schedule. If the program bombs out with a segfault he
interprets that as code in a very early stage of development. If it just
produces a garbage answer but in a nice-looking dialogue box, he interprets
that as a bit of a glitch that can be fixed.

Whilst in the long run you have to get to the root of the problem, we don't
all have the luxury of ignoring short term pressures.
 
T

Tor Rustad

Tony said:
Hi

I'm quite new to C programming - I have more of a Java background: maybe
someone here can advise me.

I'm nearly finishing a little program but it has some hard-to-find bugs
that basically lead to a couple pointers sometimes being NULL at the
wrong time. As it stands the program just bombs out when it tries to
dereference the NULL, which obviously isn't good (especially when it
happens with the customer looking on!!).

Never had that problem in front of a customer! :) Dereferencing invalid
pointers in the old days, was much more nasty, not only could we crash
the OS, but even worse things could happen, like corrupting the file system.
I don't think there's any serious problem to worry about, and what I'd

It should have been a major problem, don't count on your next costumer
being equally ignorant.
like to do is be able to ignore the dereference attempt and just carry
on - probably the next time round the loop the pointer will be OK. In
Java, I'd put a try block around the main loop, and if we catch an
exception then just jump back to the start of the main loop. What's the
corresponding thing in C?

The corresponding thing in C, would be to save environment via setjmp,
install a signal handler for SIGSEGV and do a longjmp when such a signal
occurs.

This is *not* recommended practice in C, for a number of reasons. In C,
you should fix the bugs, and tracking down NULL pointer dereferences, is
easy.

One simple method to catch your error, is via assert() in debug builds,
just put in such checks on entry to *every* function:

#include <stddef.h>
#include <assert.h>

void foo(char *pointer)
{
assert(pointer != NULL); /* check your assumptions */
...
}

int main(void)
{
char *pointer = NULL;

...
foo(pointer);

return 0;
}

for more complex memory errors, a tool like e.g. valgrind, is useful.
 
J

Joe Wright

Tony said:
Hi

I'm quite new to C programming - I have more of a Java background: maybe
someone here can advise me.

I'm nearly finishing a little program but it has some hard-to-find bugs
that basically lead to a couple pointers sometimes being NULL at the
wrong time. As it stands the program just bombs out when it tries to
dereference the NULL, which obviously isn't good (especially when it
happens with the customer looking on!!).

I don't think there's any serious problem to worry about, and what I'd
like to do is be able to ignore the dereference attempt and just carry
on - probably the next time round the loop the pointer will be OK. In
Java, I'd put a try block around the main loop, and if we catch an
exception then just jump back to the start of the main loop. What's the
corresponding thing in C?

Thanks!
Java is not interesting here. "pointers sometimes being NULL at the
wrong time." is not a bug, it's a serious design flaw.

Don't show the customer any code you know to be faulty.

There IS a serious problem to worry about: Your willingness to hide the
problem and/or work through it is frightening. No programmer worth his
salt will do that! If you are the Programmer, you cannot 'release' a
program with known bugs. If you need help, ask for it.
 
C

Chris Thomasson

Tor Rustad said:
Tony said:
Hi [...]
like to do is be able to ignore the dereference attempt and just carry
on - probably the next time round the loop the pointer will be OK. In
Java, I'd put a try block around the main loop, and if we catch an
exception then just jump back to the start of the main loop. What's the
corresponding thing in C?

The corresponding thing in C, would be to save environment via setjmp,
install a signal handler for SIGSEGV and do a longjmp when such a signal
occurs.

longjmp isn't in the list of async-signal-safe functions:

http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html

So you cannot call it from within a signal-handler. Use sigsetjmp/siglongjmp
instead. Also, be careful to not call siglongjmp from a nested
signal-handler as it results in undefined behavior:

http://opengroup.org/onlinepubs/007908799/xsh/siglongjmp.html
 
T

Tor Rustad

Chris said:
Tor Rustad said:
Tony said:
Hi [...]
like to do is be able to ignore the dereference attempt and just carry
on - probably the next time round the loop the pointer will be OK. In
Java, I'd put a try block around the main loop, and if we catch an
exception then just jump back to the start of the main loop. What's the
corresponding thing in C?

The corresponding thing in C, would be to save environment via setjmp,
install a signal handler for SIGSEGV and do a longjmp when such a
signal occurs.

longjmp isn't in the list of async-signal-safe functions:

One of the reasons I didn't recommend OP doing this, was that
from the point of ISO C, calling longjmp from a signal handler invokes
UB. However, but so does dereferencing NULL pointer. If OP want a
well-defined C program, the NULL dereference has to be removed.

IIRC, Stevens did use longjmp from a signal handler in APUE, so it
appears that this was at one point allowed in POSIX environments.
So you cannot call it from within a signal-handler. Use
sigsetjmp/siglongjmp instead. Also, be careful to not call siglongjmp
from a nested signal-handler as it results in undefined behavior:

Very little can be done in C99 signal handlers, calling siglongjmp() is
not on that list, the sigsetjmp/siglongjmp is POSIX functions (off-topic
here, but on-topic in c.u.programmer).
 
R

Randy Howard

Hi

I'm quite new to C programming - I have more of a Java background: maybe
someone here can advise me.

I'm nearly finishing a little program but it has some hard-to-find bugs
that basically lead to a couple pointers sometimes being NULL at the
wrong time. As it stands the program just bombs out when it tries to
dereference the NULL, which obviously isn't good (especially when it
happens with the customer looking on!!).

Rule #1: Don't show the customer the program before it is finished.
I don't think there's any serious problem to worry about,


This is almost certain to be a very poor belief to hold,
and what I'd
like to do is be able to ignore the dereference attempt and just carry
on

And this is probably not the right approach to handle it either.

- probably the next time round the loop the pointer will be OK.

Because of divine intervention?
In
Java, I'd put a try block around the main loop, and if we catch an
exception then just jump back to the start of the main loop. What's the
corresponding thing in C?

Detect the error, and take appropriate action when it occurs.
 
E

Eric

Randy said:
Rule #1: Don't show the customer the program before it is finished.



This is almost certain to be a very poor belief to hold,


And this is probably not the right approach to handle it either.

- probably the next time round the loop the pointer will be OK.

Because of divine intervention?


Detect the error, and take appropriate action when it occurs.
Whats really scary is that guys like this might be writing aircraft control
software. Got a NULL pointer? ah dont worry, just run it 4 or 5 times it
will go. Array too small? no problemo, there's always extra space off the
end we can use. God help us! Its no wonder that most things today that have
any kind of built in control program are pure crap (e.g. remote controls,
home routers, DVR's etc etc).
 
R

Randy Howard

Whats really scary is that guys like this might be writing aircraft control
software. Got a NULL pointer? ah dont worry, just run it 4 or 5 times it
will go.


Or a nuclear power plant, or airbag deployment code in a car, or ....
the list is quite long these days.
Array too small? no problemo, there's always extra space off the
end we can use.

Yes, and don't forget, malloc never fails. :)
God help us! Its no wonder that most things today that have
any kind of built in control program are pure crap (e.g. remote controls,
home routers, DVR's etc etc).

Yes, when everything is built by the lowest bidder, and nobody will buy
anything that's not on the top of the list, when sorted by price low to
high, then you get mostly crap.
 

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

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top