title: How to properly reset _bstr_t to `NULL`
body: <p>In the snippet bellow (simplified scenario of a loop)</p>
  
  <pre><code>_bstr_t original(OLESTR("MyString")); // ref-count = 1
  _bstr_t another;
  another = original; // ref-count = 2
  // do something with another
  another.Assign(NULL); // expected: ref-count = 1, and another = NULL
  // reset another to NULL before doing other operations
  </code></pre>
  
  <p>What I expect after <code>another.Assign(NULL)</code> is:</p>
  
  <ul>
  <li><code>SysFreeString()</code> is NOT called</li>
  <li><code>another</code> is set to <code>NULL</code></li>
  <li>ref-count is decremented to 1 </li>
  <li><code>original</code> has <code>ref count=1</code> with existing <code>BSTR</code> content.</li>
  </ul>
  
  <p>What happened:</p>
  
  <ul>
  <li><code>SysFreeString()</code> is called for underlying <code>BSTR</code> of both <code>another</code> and <code>original</code></li>
  <li><code>another</code> is set to <code>NULL</code></li>
  <li>ref-count of <code>original</code> remains 2 </li>
  </ul>
  
  <p><code>another.Assign(NULL)</code> seems to deallocate the underlying <code>BSTR</code> for both <code>original</code> and <code>another</code>.<br>
  We had unexpected crash because during coding I thought <code>_bstr_t::Assign()</code> will decrement the ref count instead of straight away deallocating the <code>BSTR</code>.</p>
  
  <p>How do I properly reset <code>another</code> to <code>NULL</code> without affecting <code>original</code>?  </p>
  
  <p>Please find bellow implementation of <code>Assign</code> from <code>VC++ 6</code>.</p>
  
  <pre><code>// assignment operator copies internal data and increases reference count
  inline _bstr_t&amp; _bstr_t::operator=(const _bstr_t&amp; s) throw()
  {
      const_cast&lt;_bstr_t*&gt;(&amp;s)-&gt;_AddRef();
      _Free();
      m_Data = s.m_Data;
  
      return *this;
  }
  // but _bstr_t::Assign() calls _bstr_t::Data_t::Assign() 
  // without touching ref count
  inline void _bstr_t::Assign(BSTR s) throw(_com_error)
  {
      if (m_Data != NULL) {
          m_Data-&gt;Assign(s); 
      } 
      else {
          m_Data = new Data_t(s, TRUE);
          if (m_Data == NULL) {
              _com_issue_error(E_OUTOFMEMORY);
          }
      }
  }
  // it calls _bstr_t::Data_t::_Free() instead of _bstr_t::_Free() !
  inline void _bstr_t::Data_t::Assign(BSTR s) throw(_com_error)
  {
      _Free();
      if (s != NULL) {
          m_wstr = ::SysAllocStringByteLen(reinterpret_cast&lt;char*&gt;(s), 
                                              ::SysStringByteLen(s));
      }
  }
  // this _Free() straight away deallocates the BSTR!
  inline void _bstr_t::Data_t::_Free() throw()
  {
      if (m_wstr != NULL) {
          ::SysFreeString(m_wstr);
      }
  
      if (m_str != NULL) {
          delete [] m_str;
      }
  }
  // properly decrements ref count
  inline void _bstr_t::_Free() throw()
  {
      if (m_Data != NULL) {
          m_Data-&gt;Release();
          m_Data = NULL;
      }
  }
  </code></pre>