2016-04-25 39 views
-1

如果我有一个类或结构是这样的:DirectX COM对象在这种情况下的内存泄漏?

bool localScopeFunc() 
 
{ 
 
    bool result; 
 
    IDXGIFactory* pFactory; 
 
    IDXGIAdapter* pAdapter; 
 
    
 
    result = //Do something here with the objects 
 
\t if (!result) return false; 
 
    
 
\t result = //Do something here with the objects 
 
\t if (!result) return false; 
 
    
 
\t result = //Do something here with the objects 
 
\t 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

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

这里的解决方案其实很简单:使用Microsoft::WRL::ComPtr。无论您如何离开示波器,该智能指针都会根据需要调用Release。

要注意的另一件事是COM对象不会返回错误作为布尔。他们是HRESULT。你不应该忽略它们,因为如果函数返回HRESULT它可能会失败。你也不应该使用== S_OK之类的。您应该使用宏,SUCCEEDED宏或DX::ThrowIfFailed之类的东西。

#include <wrl/client.h> 

using Microsoft::WRL::ComPtr; 

bool localScopeFunc() 
{ 
    ComPtr<IDXGIFactory> pFactory; 
    ComPtr<IDXGIAdapter> pAdapter; 

    HRESULT result = //Do something here with the objects 
    if (FAILED(result)) return false; 

    result = //Do something here with the objects 
    if (FAILED(result)) return false; 

    result = //Do something here with the objects 
    if (FAILED(result)) return false; 

    // And so on...... 

    return true; // If all passes 
} 

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

+0

谢谢查克。到目前为止,我只使用原始指针,但ComPtr和unique_pointer对于这类事情似乎非常方便。 ComPtr会与unique_pointer或shared_pointer共享更多的相似性吗? 此外,我一直在试图找出两个COM对象方法.get()和.getAddressOf()之间的区别。我无法理解MSDN的意思,因为对我而言,这听起来是相当的。我应该传递.get()还是getAddressOf()作为参数?谢谢。 – Zebrafish

+0

''ComPtr''是一个引用计数的共享智能指针,所以在逻辑上与''shared_ptr''类似。查看[this](https://github.com/Microsoft/DirectXTK/wiki/ComPtr)查看''ComPtr''的使用提示,我特别说明了为什么你会看到''Get''和''GetAddressOf ''与Direct3D参数一起使用。 –

+0

谢谢,我读了大约3次。它慢慢地沉入其中。区别在于get()是指针,getAddressOf()是指针的地址,您可以将它传递给指向指针参数的指针的函数。 另一件事,如果你不介意解释。通常如果你创建了一个指向某个东西的指针,那么你可以在检查它是否为空之后马上指出失败。所以当我去的时候(!ptr)返回false; ,是否需要更改为if(!ptr.get())返回false; ?作为一个独特的ptr不是一个指针本身,而是一个包装。 – Zebrafish

相关问题