COMPTR的内存泄漏

Memory Leak with CComPtr

本文关键字:泄漏 内存 COMPTR      更新时间:2023-10-16

i使用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有任何步骤?

您有内存泄漏,因为您正当 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函数应每线程仅调用一次,而不是每个用户函数。