【问题标题】:Memory Leak with CComPtr内存泄漏与 CComPtr
【发布时间】:2019-05-03 02:50:42
【问题描述】:

我使用crtdbg检测泄漏位置,调用new时出现内存泄漏

CComPtr<IDBColumnInfo> m_spColumnInfo
CComPtr<CDBColumnInfo> spResult = new CDBColumnInfo(); //Memory leak here
//another logic come here to set data to spResult
//another logic come here to set data to spResult
//another logic come here to set data to spResult
m_spColumnInfo = static_cast<IDBColumnInfo*>(spResult.Detach());
spResult.Release();

spResult 是否需要执行任何步骤?

【问题讨论】:

  • 为什么需要spResult.Detach()?为什么不这样做:m_spColumnInfo = static_cast&lt;CDBColumnInfo*&gt;(spResult)?我有一段时间没有使用CComPtr,但是documentation 表示operator= 会增加引用计数,所以通过使用Detach,我认为你最终会得到一个额外的AddRef 而没有当您尝试转移所有权时,对应的Release
  • 没有更多细节了。尝试用我建议的行替换 spResult.Detach() 行。
  • @jamesdlin 我在这个函数中遇到异常pastebin.com/LkWT2bhU
  • 查看您的实际代码后:您根本不需要delete spResult。另外,我会将spResult 声明为CComPtr&lt;IDBColumnInfo&gt;,然后完全摆脱static_cast
  • @jamesdlin 我改成CComPtr&lt;IDBColumnInfo&gt; spResult = new CDBColumnInfo();,但是CDBColumnInfo 的某些功能无法被spResult 访问。例如HRESULT CDBColumnInfo::GetField (LPCOLESTR fieldName )

标签: c++ memory-leaks visual-leak-detector


【解决方案1】:

您有内存泄漏,因为您对 CDBColumnInfo 对象的引用计数管理不善。

当您初始化spResult 时,对象的引用计数被初始化为1。当您调用spResult.Detach() 时,对象的引用计数仍然为1,因为Detach() 不会减少它。当分离的指针被分配给m_spColumnInfo时,对象的引用计数增加为2。当m_spColumnInfo稍后被释放时,它减少对象的重新计数为1,并且对象被泄露。

您根本不应该分离spResult。将其原样分配给m_spColumnInfo,这会将引用计数增加到2,然后让spResult 正常超出范围,将引用计数减少到1,留下m_spColumnInfo 唯一的活动引用。稍后释放m_spColumnInfo 时,引用计数将减为0,并释放对象。

您根本不应该尝试手动管理引用计数。这违背了使用CComPtr 的全部目的。

CComPtr<IDBColumnInfo> m_spColumnInfo;

...

{
    CComPtr<CDBColumnInfo> spResult = new CDBColumnInfo();
    //set data to spResult
    m_spColumnInfo = spResult;
}

另外,附带说明一下,您的函数根本没有业务调用 CoInitialize()CoUninitialize()!您需要从函数中删除这些调用(特别是因为在退出函数的大多数代码路径中,您的函数甚至没有调用 CoUninitialize())。这些调用不是你的函数的责任。调用函数的线程负责决定它需要如何为自己初始化 COM。这些 COM 函数应该每个线程只调用一次,而不是每个用户函数。

【讨论】:

    猜你喜欢
    • 2011-10-16
    • 2019-08-08
    • 2012-08-21
    • 2016-01-25
    • 2015-04-15
    • 2014-03-26
    • 2012-07-09
    • 2011-01-04
    • 2015-06-28
    相关资源
    最近更新 更多