Trick To Prevent Error “Safe” Pointer Dereferencing

In your first C/C++ programming class you’ll eventually learn about this thing called indirection. In order to use that concept you get introduced to “pointers”. They are amazing, powerful, and also dangerous if not used carefully. To protect against the “danger” of using pointers we learn a very trivial, but intensive method of an attempt to validate the pointer before it is “dereferenced”.  We end up with something like this:

int deref(int * intPtr)
{
    int derefThing;
    if(intPtr != 0)
    {
         derefThing = *intPtr;
    }
    return derefThing;
}

With any pointer we can only check for NULL or 0. if that operation is called and 0 is passed in as the value of the pointer, it will result in a segmentation fault or a “runtime error” depending on the Operating System you are on and the compiler if we didn’t defend against that from happening.

I’d like to convince everyone that segmentation faults and runtime errors are good. If you’re programming you should learn how to use a “debugger”. This is your opportunity to learn if you haven’t used one before. If built in “debug” mode and a segmentation fault occurs or runtime error, with the proper debugging tools you can find out exactly where and when the fault occured!

Using a debugger is a complete other topic so, getting back to the point there’s a simple thing we can do to avoid having to type all these logical expressions to defend against the “dangers” of utilizing pointer values. See below:

int deref(int * intPtr)
{
    int & derefThing(*intPtr);
    return derefThing;
}

Wait! What is this?! It does exactly the same thing and we cut the number of lines of code in half. Yes! What is this magical “&” thing? It’s a reference! They are more sophisticated than pointers, but essentually do the same thing under the hood after complilation. One thing to keep in mind is “references” need to be initialized at construction to exist. Therefore we must initialize it to the dereferenced pointer value to even create it. References must refer to a “real” memory attribute/object, therefore, must be initialized to something that actually exists. What this does is allow you to dereference a pointer a single time, and use the reference as much as you want without having to do a bunch of logical expressions to “protect” an invalid pointer from being accessed.

This is where we need to “trust” our toolset and operating systems to debug invalid values passed in as a pointer. If the pointer is successfully dereferenced and single time and assigned to a reference then we’re “gold”. If not a segmentation fault or runtime error will occure and we simply debug the root cause of the problem.

At the end of the day, you can say, “look boss, I did what Joe did, with half the code that we don’t need to test!” You also get the info necessary to get to the root of a “pointer” problem in the first place with less code to sort through.