Search code examples
c++destructorraii

Should pointers to "raw" resources be zeroed in destructors?


When I wrap "raw" resources in a C++ class, in destructor code I usually simply release the allocated resource(s), without paying attention to additional steps like zeroing out pointers, etc. e.g.:

class File
{
public:
  ...

  ~File()
  {
    if (m_file != NULL)
      fclose(m_file);
  }

private:
  FILE * m_file;
};

I wonder if this code style contains a potential bug: i.e. is it possible that a destructor is called more than once? In this case, the right thing to do in the destructor would be to clear pointers to avoid double/multiple destructions:

~File()
{
  if (m_file != NULL)
  {
    fclose(m_file);
    m_file = NULL; // avoid double destruction
  }
}

A similar example could be made for heap-allocated memory: if m_ptr is a pointer to memory allocated with new[], is the following destructor code OK?

// In destructor:
delete [] m_ptr; 

or should the pointer be cleared, too, to avoid double destruction?

// In destructor:
delete [] m_ptr;
m_ptr = NULL; // avoid double destruction

Solution

  • No. It is useful if you have a Close() function or the like:

    void Close()
    {
        if (m_file != NULL)
        {
            fclose(m_file);
            m_file = NULL;
        }
    }
    ~File()
    {
        Close();
    }
    

    This way, the Close() function is idempotent (you can call it as many times as you want), and you avoid one extra test in the destructor.

    But since destructors in C++ can only be called once, assigning NULL to pointers there is pointless.

    Unless, of course, for debuggin-purposes, particularly if you suspect a double-delete.