如何正确释放 ID3D11ShaderResourceView** 以避免内存泄漏?

Posted

技术标签:

【中文标题】如何正确释放 ID3D11ShaderResourceView** 以避免内存泄漏?【英文标题】:How can I properly release a ID3D11ShaderResourceView** to avoid memory leaks? 【发布时间】:2015-09-29 21:26:31 【问题描述】:

我把它作为一个类的私有成员。

ID3D11ShaderResourceView** texture_pool;

我在类构造函数中将其设置为 NULL,如下所示:

texture_pool = NULL;

然后我在类初始化中这样初始化:

texture_pool = new ID3D11ShaderResourceView*[texture_count];
for (int n = 0; n < texture_count; n++) texture_pool[n] = NULL;

在类析构函数中我这样释放它:

for (int n = 0; n < texture_count; n++) SAFE_RELEASE(texture_pool[n]);
SAFE_DELETE_ARRAY(texture_pool);

但有时我的程序在我退出时会崩溃,并且调试器指向这一行是导致崩溃的原因:

for (int n = 0; n < texture_count; n++) SAFE_RELEASE(texture_pool[n]);

如果我删除该行,一切都会顺利进行,但我担心如果我不释放数组可能会导致内存泄漏。

那么,我可以删除那条线,然后一切都会被妥善清理吗?

这些是释放和删除指令的定义行:

#define SAFE_RELEASE(p)  if ( (p) )  (p)->Release(); (p) = 0;  
#define SAFE_DELETE(a) if( (a) != NULL ) delete (a); (a) = NULL;
#define SAFE_DELETE_ARRAY(a) if( (a) != NULL ) delete[] (a); (a) = NULL;

【问题讨论】:

您是否尝试过使用调试器单步执行代码以查看在您的析构函数的 for 循环中崩溃的位置?您的实现可能编写正确,但您可能试图释放在析构函数调用时无效的内容。 我也注意到了一些关于你的宏,你可以参考下面的答案,看看这是否解决了你的问题。 【参考方案1】:

你已经展示了这个:

#define SAFE_RELEASE(p)  if ( (p) )  (p)->Release(); (p) = 0;  
#define SAFE_DELETE(a) if( (a) != NULL ) delete (a); (a) = NULL;
#define SAFE_DELETE_ARRAY(a) if( (a) != NULL ) delete[] (a); (a) = NULL;

试试这个:

#ifndef SAFE_RELEASE
    #define SAFE_RELEASE(p)  if(p)  (p)->Release(); (p) = NULL;  
#endif

#ifndef SAFE_DELETE
     #define SAFE_DELETE(p)  if(p)  delete (p); (p) = nullptr;  
#endif

#ifndef SAFE_DELETE_ARRAY
    #define SAFE_DELETE_ARRAY(p)  if(p)  delete[](p); (a) = nullptr;  
#endif

使用宏时,您需要小心使用“()”和“”。

您也不需要 (p) != nullptr 检查,因为当您有 if(p) 时,它只会在此检查返回 true 指示指针有效且不为 null 时执行下一条语句。

您还缺少宏定义周围的#ifndef#endif

如果您的编译器不支持nullptr,那么您可以改用NULL,但nullptr 更简洁易读。

【讨论】:

@Haalef 让我知道这是否解决了您的问题,以便我们可以从那里查看您是否尝试让 DirectX 释放无效对象。 感谢@Francis Cugler,您的代码更简洁,应该避免不使用保护措施#ifndef 和#endif 可能出现的问题。然而它并没有解决问题。有趣的是,当我在 Visual Studio 中运行调试或发布版本时一切正常,但是当我直接在操作系统中执行生成的 .exe 文件时,它在退出时崩溃,我为解决这个问题所做的工作是现在我使用向量作为数组的容器并像以前一样清理析构函数中的每个元素,它似乎已经解决了这个问题。现在到处都可以正常工作。 很高兴看到您找到了可行的解决方案。那将是我的下一个建议,即使用与数组相对的向量。

以上是关于如何正确释放 ID3D11ShaderResourceView** 以避免内存泄漏?的主要内容,如果未能解决你的问题,请参考以下文章

如何正确释放 ID3D11ShaderResourceView** 以避免内存泄漏?

如何在win7上将ID3D11Texture2D内容复制到IMFSample?

C2259:“ID3D11ShaderResourceView”无法实例化抽象类 - DX11

DirectX:以 DXGI_FORMAT_NV12 格式从 ID3D11Texture2D 获取 RGB 数据的最佳方法?

ID3D11Texture2D 到 ID2D1Bitmap,可以吗?

D3D11笔记——Resource基本概念