如果我有这样的类或结构:
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;
}

答案 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。