Where’d that null come from?

One of the most annoying things that can happen to a computer programmer is the dreaded NullPointerException, or in C++, the segfault that occurs due to dereferencing a null pointer. The null pointer error has this ‘feature’ which makes it a ‘pleasure’ to debug: the source of the null can be arbitrarily far away from its use. I’ve come up with an interesting technique for tracking down the source:

  1. Use the NullObject pattern, so that the null pointer instead points at a null-behaving object.
  2. Gift all NullObjects with an identification number.
  3. Place an assertion that stops the debugger at the point when a NullObject with the same Id as the one which originally caused the NullPointerException is constructed.

That first part will likely be the trickiest to pull off. In C++ there are several issues to consider. Is the null pointer of a user-created type (Thing*) or built-in (int*)? Is it easy to introduce a constructor which automatically changes Thing *t = null; into Thing *t = new NullThing()? Can this coercion also be done for subclasses (because a null subclass pointer can be type-converted to a base class pointer before the dereference)? Is it worth trying to change all Thing pointers to Thing references, just to make sure you catch everything?

One final issue: this technique will only work for deterministic code. Otherwise no guarantee can be made on the issuing of Id’s within the NullObject constructor (easiest done with a global incrementing counter).