Chapter 9. Dereferencing NULL Pointers

One of the most frequent reasons for program crashes (a.k.a. core dumps under Unix) is an attempt to dereference a NULL pointer. As we saw in the previous chapter, both smart pointers discussed there—the RefCountPtr and the ScopedPtr—have run-time diagnostics for that. However, not every pointer is a smart pointer that has ownership of some object. To diagnose an attempt to dereference a pointer that does not have ownership of an object, I’ll introduce here a “semi-smart” pointer that does not delete the object it points to. Let’s take a look at the public portion of it in the file scpp_ptr.hpp:

// Template pointer, does not take ownership of an object.
template <typename T>
class Ptr {
 public:

  explicit Ptr(T* p=NULL)
  : ptr_(p) {
  }

  T* Get() const {
    return ptr_;
  }

  Ptr<T>& operator=(T* p) {
    ptr_ = p;
    return *this;
  }

  T* operator->() const {
    SCPP_TEST_ASSERT(ptr_ != NULL,
      "Attempt to use operator -> on NULL pointer.");
    return ptr_;
  }

  T& operator* () const {
    SCPP_TEST_ASSERT(ptr_ != NULL,
      "Attempt to use operator * on NULL pointer.");
    return *ptr_;
  }

Despite the presence of operator=, this is not an assignment operator that would tell the compiler what to do when we try to assign one Ptr<T> to another. The assignment operator for this class, if we had writthen one, would be declared as:

Ptr<T>& operator=(const Ptr<T>& that);

Note that the operator= declared in the preceding class has a different signature: it includes a raw pointer p

Get Safe C++ now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.