What’s the one thing you should never do with a NULL pointer?

In the C programming language (and in C++), NULL pointers are often used as sentinels for detecting the end of a data structure (e.g., the last node’s next pointer on a linked list, the first node’s previous pointer on a doubly-linked list, child pointers in the leaf node of a tree, a head pointer to a data structure that contains no nodes, etc.).

A NULL pointer is also commonly used:

  • as an initializer to a “known state,” to avoid a random address sitting around in a pointer variable,
  • to indicate a “no data available” return value from a function,
  • to indicate that no memory block is available, when calling functions from the malloc family.

This is not an exhaustive list, but it hits the highlights.  And yet, other than testing whether the pointer is NULL, there’s really not much you can or should do with a NULL pointer.

Don’t dereference a NULL pointer or do anything that causes it to be dereferenced, directly or indirectly. The behavior, if you do, is undefined, and can range from a segfault or access violation to silently destroying an interrupt vector in low memory.

What might cause a NULL pointer to be dereferenced?  Here’s a partial list:

  • Obviously, dereferencing the pointer to read the value it points to, as in x = *p.
  • Of course, dereferencing the pointer to change the value it points to, as in *p = y.
  • Using array indexing to read a value, as if the pointer were pointing to the base address of an array, as in p[0] or p[z]. After all, p[0] is equivalent to *p, and p[z] is equivalent to *(p + z).
  • Using array indexing to write a value, as if the pointer were pointing to the base address of an array, as in p[0] = y or p[z] = y.
  • Passing the pointer as an argument into any function that, directly or indirectly, causes any of the above to occur.

That said, in some environments (e.g., some freestanding environments), dereferencing a NULL pointer is effectively accessing memory address 0, which might be a perfectly valid (if non-portable) thing to do, if you really know what you’re doing. But in a protected operating system environment, it is not a valid thing for an application to do.