C is largely based on raw pointers and one of the most often asked questions is when is a pointer a valid one. The reason is that dereferencing an invalid pointer generates an access violation exception (0xC0000005) and if not caught, the program crashes.
You quickly learn there is IsBadReadPtr
function available and its variants. You look at the name and think you found the best way to check the pointer’s validity. That is until you notice, that Microsoft documentation says these functions are obsolete and warns against using them in no uncertain terms. And Raymond Chan from Microsoft provides details at his blog The Old New Thing.
Then, you think this is such basic C/C++ question, there must be a way to do it. You start searching the Internet and slowly come to realize, that there is no way to check validity of raw pointers.
However, there are best practices how to guard against invalid pointers.
Best practices to guard against bad pointers
- Initialize all pointers to
nullptr
. - After deleting an object, set its pointer to
nullptr
. - Check pointer for non-zero value before dereferencing it.
The above best practices will not prevent you from dereferencing invalid raw pointers altogether. For example, it does not prevent somebody from passing an invalid pointer through the API. In that situation, you have to accept GIGO, garbage in garbage out paradigm.
How to check if pointer has non-zero value?
There are few ways of checking if a pointer points to nothing. If it does not, it has a non-zero value. Still does not make it valid, but you have done your best.
if (p == 0)
: Check against number 0 which is typed as int. OK approach.if (p == NULL)
: NULL is macro defined as 0. Slightly better, makes your application more readable.if (p == nullptr)
: Check against C++11 keyword. Best, clean approach.
The above triad is nicely explained by Kate Gregory in her “C++ Fundamentals” class on Pluralsight, in chapter “Pointers”. For another take on the same read Bjarne Stroustrup.
Conclusion
There is no good way to check if a raw pointer is valid or not, in other words if it can be safely dereferenced or not. You should seriously consider not using raw pointers in your code and start using smart pointers unique_ptr
and shared_ptr
from C++11.