title: Calling Inherited IUnknown::Release() in a destructor
body: <p>Why does calling the inherited IUnknown::Release() function on a IWICImagingFactory object in a destructor cause a "CXX0030: Error: expression cannot be evaluated" to be shown each entry in the object's virtual function table (__vfptr)?</p>
  
  <p>This is in reference to an earlier question I posted but I've since realized that the problem only occurs in the destructor. The virtual function table appears valid anywhere else I have checked. However, once in the destructor all entries are shown with the CXX0030 error and attempting to call the inherited IUknown::Release() fails.</p>
  
  <p>Edit: Here is some code to demonstrate:</p>
  
  <pre><code>HRESULT DemoApp::CreateDeviceIndependentResources()
  {
  HRESULT hr;
  
  
  hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &amp;mpDirect2DFactory);
  
  
  if (SUCCEEDED(hr))
  {
      hr = CoCreateInstance(
          CLSID_WICImagingFactory,
          NULL,
          CLSCTX_INPROC_SERVER,
          IID_PPV_ARGS(&amp;mpWICFactory)
          );
  }
  
  //CoCreateInstance returns S_OK.
  //Other unrelated code here.
  }
  
  HRESULT DemoApp::CreateDeviceResources()
  {
  HRESULT hr;
  //Other unrelated code here for creating device-dependant resources.
  //mpBackgroundBitmap is a ID2D1Bitmap*.
      if(SUCCEEDED(hr))
      {
          hr = LoadBitmapFromFile(
              mpRenderTarget,
              mpWICFactory,
              L".\\background.png",
              0,
              0,
              &amp;mpBackgroundBitmap);
      }
  }
  
  
  //The below LoadBitmapFromFile() code is taken directly from an MSDN sample.
  //I didn't write it.
  
  HRESULT DemoApp::LoadBitmapFromFile(
  ID2D1RenderTarget *pRenderTarget,
  IWICImagingFactory *pIWICFactory,
  PCWSTR uri,
  UINT destinationWidth,
  UINT destinationHeight,
  ID2D1Bitmap **ppBitmap
  )
  {
  IWICBitmapDecoder *pDecoder = NULL;
  IWICBitmapFrameDecode *pSource = NULL;
  IWICStream *pStream = NULL;
  IWICFormatConverter *pConverter = NULL;
  IWICBitmapScaler *pScaler = NULL;
  
  HRESULT hr = pIWICFactory-&gt;CreateDecoderFromFilename(
      uri,
      NULL,
      GENERIC_READ,
      WICDecodeMetadataCacheOnLoad,
      &amp;pDecoder
      );
  
  if (SUCCEEDED(hr))
  {
      // Create the initial frame.
      hr = pDecoder-&gt;GetFrame(0, &amp;pSource);
  }
  if (SUCCEEDED(hr))
  {
  
      // Convert the image format to 32bppPBGRA
      // (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED).
      hr = pIWICFactory-&gt;CreateFormatConverter(&amp;pConverter);
  
  }
  
  
  if (SUCCEEDED(hr))
  {
      // If a new width or height was specified, create an
      // IWICBitmapScaler and use it to resize the image.
      if (destinationWidth != 0 || destinationHeight != 0)
      {
          UINT originalWidth, originalHeight;
          hr = pSource-&gt;GetSize(&amp;originalWidth, &amp;originalHeight);
          if (SUCCEEDED(hr))
          {
              if (destinationWidth == 0)
              {
                  FLOAT scalar = static_cast&lt;FLOAT&gt;(destinationHeight) / static_cast&lt;FLOAT&gt;(originalHeight);
                  destinationWidth = static_cast&lt;UINT&gt;(scalar * static_cast&lt;FLOAT&gt;(originalWidth));
              }
              else if (destinationHeight == 0)
              {
                  FLOAT scalar = static_cast&lt;FLOAT&gt;(destinationWidth) / static_cast&lt;FLOAT&gt;(originalWidth);
                  destinationHeight = static_cast&lt;UINT&gt;(scalar * static_cast&lt;FLOAT&gt;(originalHeight));
              }
  
              hr = pIWICFactory-&gt;CreateBitmapScaler(&amp;pScaler);
              if (SUCCEEDED(hr))
              {
                  hr = pScaler-&gt;Initialize(
                          pSource,
                          destinationWidth,
                          destinationHeight,
                          WICBitmapInterpolationModeCubic
                          );
              }
              if (SUCCEEDED(hr))
              {
                  hr = pConverter-&gt;Initialize(
                      pScaler,
                      GUID_WICPixelFormat32bppPBGRA,
                      WICBitmapDitherTypeNone,
                      NULL,
                      0.f,
                      WICBitmapPaletteTypeMedianCut
                      );
              }
          }
      }
      else // Don't scale the image.
      { 
          hr = pConverter-&gt;Initialize(
              pSource,
              GUID_WICPixelFormat32bppPBGRA,
              WICBitmapDitherTypeNone,
              NULL,
              0.f,
              WICBitmapPaletteTypeMedianCut
              );
      }
  }
  if (SUCCEEDED(hr))
  {
  
      // Create a Direct2D bitmap from the WIC bitmap.
      hr = pRenderTarget-&gt;CreateBitmapFromWicBitmap(
          pConverter,
          NULL,
          ppBitmap
          );
  }
  
  SafeRelease(&amp;pDecoder);
  SafeRelease(&amp;pSource);
  SafeRelease(&amp;pStream);
  SafeRelease(&amp;pConverter);
  SafeRelease(&amp;pScaler);
  
  return hr;
  }
  
  //Now I call SafeRelease() in my destructor and the virtual function table entires are showing the error.
  DemoApp::~DemoApp()
  {
  SafeRelease(&amp;mpDirect2DFactory);
  SafeRelease(&amp;mpWICFactory); //here is the problem apparently
  SafeRelease(&amp;mpDWriteFactory); 
  SafeRelease(&amp;mpRenderTarget);
  SafeRelease(&amp;mpBackgroundBitmap);
  
  }
  
  //SafeRelease is defined as:
  template&lt;class Interface&gt;
  inline void SafeRelease(Interface** ppInterfaceToRelease)
  {
  if(*ppInterfaceToRelease != NULL)
  {
      (*ppInterfaceToRelease)-&gt;Release();
      (*ppInterfaceToRelease) = NULL;
          }
  
  }
  </code></pre>
  
  <p>The problem is when I call SafeRelease() on the WICFactory object, I get:
  First-chance exception at 0x0024e135 in DemoApp.exe: 0xC0000005: Access violation reading location 0x6d5c28f0.
  Unhandled exception at 0x0024e135 in DemoApp.exe: 0xC0000005: Access violation reading location 0x6d5c28f0.</p>