在这种情况下使用DirectX COM对象的内存泄漏?

时间:2016-04-25 02:21:50

标签: c++ memory directx direct3d

如果我有这样的类或结构:



bool localScopeFunc()
{
   bool result;
   IDXGIFactory* pFactory;
   IDXGIAdapter* pAdapter; 
  
    result = //Do something here with the objects
	if (!result) return false;
  
	result = //Do something here with the objects
	if (!result) return false;
  
	result = //Do something here with the objects
	if (!result) return false;
  // And so on......
  
  
  //___Do cleanup here___//
  pFactory->Release(); pFactory = nullptr;
  pAdapter->Release(); pAdapter = nullptr;
   
  return true; // If all passes
}




如果在此函数期间的某个时刻失败并返回false,则它不会在结束时进行清理,因此不会在任何对象上调用 - > Release()。这是否意味着内存泄漏?

如果是这样,我无法找到一种可行的方法,因为有时我会有一个函数调用列表,在每个阶段初始化一些新东西,如果我必须清理一切相反,它看起来像这样:



int main()
{
 if (!initTime())    {return -1;}
 if (!initD3D())     {shutDownTime(); return -2;}
 if (!initCamera())  {shutDownD3D(); shutDownTime(); return -3;}
 if (!initSound())   {shutDownCamera(); shutDownD3D(); shutDownTime(); return -3;}
 if (!initPhysics()) {shutDownSound(); shutDownD3D(); shutDownTime(); return -4;}
// And so on.
 
 return 0; 
}




1 个答案:

答案 0 :(得分:1)

是的,它会泄漏,因为你正在逃避清理。 COM对象使用引用计数,并且交易的计数必须准确,以便系统在正确的时间删除内存。

此处的解决方案实际上非常简单:使用timeout = 100; /* 0.1 s */ OSSemPend(rtos_sem_p, timeout, OS_OPT_PEND_BLOCKING, NULL, &err); ... OSSemPend(rtos_sem_p, timeout, OS_OPT_PEND_BLOCKING, NULL, &err); ... 。无论你如何离开范围,这个智能指针都需要在需要时调用Release。

另一件需要注意的事情是,COM对象不会像bool那样返回错误。他们是HRESULT。你不应该忽略它们,因为如果函数返回一个HRESULT它可能会失败。你也不应该使用== S_OK等。您应该使用Microsoft::WRL::ComPtr宏,FAILED宏或类似DX::ThrowIfFailed的内容。

SUCCEEDED

有关使用ComPtr的更多信息,请参阅this