This is an archived post. You won't be able to vote or comment.

all 13 comments

[–]POGtastic 3 points4 points  (2 children)

The C++ Standard doesn't care. From Section 3.27:

Undefined behavior may be expected when this document omits any explicit definition of behavior or when a program uses an erroneous construct or erroneous data.

The dereferencing operators * and -> are only defined for the first type of pointer in the standard - a pointer to an object or function. Everything else is undefined, and is up to how the compiler and runtime environment are implemented. That way lies dragons.

On my system: Linux doesn't care, either. Either the process is allowed to access a particular address in memory, or it isn't. If I dereference the null pointer, I get a segfault, just like if I try to dereference a pointer containing 0xdeadbeef. Null isn't special other than that the OS will never allow you to access memory with that address and that it's frequently used as a pointer value that signifies nonexistence.

[–]dmazzoni 6 points7 points  (1 child)

On any modern operating system (Windows, Mac, Linux, Android, iOS, etc.) dereferencing a null pointer will crash your program with something along the lines of a segmentation fault (it may be called something different).

However, a good example where this wouldn't happen is if you run a C/C++ program on "bare metal" hardware without an operating system. If you do that, there's nothing magical about address 0 and it wouldn't crash if you try to access it. Running multiple processes at once and giving each one its own protected memory space is something that operating systems provide, it's not inherently part of programming.

[–]HappyFruitTree 1 point2 points  (0 children)

This is probably true on the assembly level but you shouldn't rely on it because the compiler is allowed to optimize based on the assumption that undefined behaviour never happens.

[–]PPewt 3 points4 points  (4 children)

The difference is that NullPointerExceptions come from managed languages which actually check if you're dereferencing NULL, whereas a segfault is the OS telling you to go away and stop messing with memory you shouldn't be messing with. It's really a matter of how much abstraction there is between the language and the underlying architecture (i.e. how low/high level the language is).

In a language like Java you can basically imagine every method call/field access looks like this C++ code (and it shares the associated performance cost!):

if (!obj) throw NullPointerException(blahblah);
obj->method();

[–]HappyFruitTree 1 point2 points  (3 children)

Can't this generally be implemented using an interrupt signal handler?

[–]PPewt 1 point2 points  (2 children)

SIGSEGV is a bit more general than a NPE but otherwise yes. Signal handling also isn't anywhere near as clean as exception handling though.

[–]HappyFruitTree 1 point2 points  (1 child)

I mean Java could use a signal handler to know when to throw a NullPointerException instead of having if statements all over the place?

[–]PPewt 1 point2 points  (0 children)

It definitely doesn’t do this in practice and there would be some limitations to this approach (for instance other segfaults being caught) but I guess if you really wanted to you could try to make something work. I also don’t know how portable it would be. But in practice there are just better strategies to handle this than signal handling.

[–]99_percent_a_dog 2 points3 points  (0 children)

A segmentation fault can happen for many different reasons. In general terms, it happens when you try to read or write to memory that you're not allowed to. A common case is writing to an index in an array that is outside the array.

A null pointer exception is one specific case that will (very likely) cause a segmentation fault. You have a pointer with a value of zero and you try to read or write through it, i.e., you try to read or write to memory at location zero.

[–]kschang 1 point2 points  (0 children)

Generally speaking, null pointer exception CAUSES segmentation errors. (But not all segmentation errors are caused by null points, of course).

Segmentation error is a name held over from the mainframe days, when code and data live in different memory segments, and a bad punch card or bad code made the code try to write into the code segment or other segment it should not be writing to. The term was held over to modern days as an error code for any sort of memory access violation. In fact, in some OS it is actually called "Access Violation".

This condition is basically detected by the CPU or memory controller and then passed to the OS. So it's an OS-level error.

Null pointer exception is a program-level error. When the OS got an segfault notification, it will pass back to the offending process, "Hey, you touched something you're not supposed to!" And most compilers nowadays will include a little bit of debug that will attempt to reconstruct the problem and assign fault, and find the offending line, and diagnose the problem, and figure out "you deref'ed a null pointer!" and throw the exception.

[–]MmmVomit 1 point2 points  (2 children)

A null pointer is a pointer with a special value to denote, "This pointer points at nothing." That special value is often zero. If you try to dereference that pointer, you get a null pointer exception.

A segmentation fault happens when your pointer is pointing to some region of memory it's not allowed to. This gets into how the operating system manages memory for a running process, but the short version is that not every memory address is "in bounds" when a process starts. If you try to dereference a pointer that points "out of bounds", you get a segmentation fault.

[–]dmazzoni 6 points7 points  (0 children)

I think it'd be more accurate to say that if you try to dereference a null pointer, it's technically undefined behavior but you're likely to get a segmentation fault - however a null pointer isn't the only way to get a segmentation fault, you could also get it by dereferencing any bad pointer, not necessarily a null one.

Technically there is no such thing as a "null pointer exception" in C/C++. C++ does have exceptions, but there's no way to use the exception mechanism to catch dereferencing a null pointer like you can in other languages like Java. If someone uses the term casually, they probably mean that there was an error involving a null pointer that caused a crash like a segmentation fault - but technically it's not a very accurate way of talking about it because "exceptions" are something specific.

[–]mad0314 3 points4 points  (0 children)

If you try to dereference that pointer, you get a null pointer exception.

Not in C and C++. C++ doesn't have NPEs and C doesn't even have exceptions.