我使用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时,对象的refcount初始化为1。调用spResult.Detach()时,对象的refcount仍为1,因为Detach()不会递减。然后,将分离的指针分配给m_spColumnInfo时,对象的refcount会增加为2。稍后释放m_spColumnInfo时,它将对象的recount减为1,并且该对象会泄漏。

您根本不应该分离spResult。将其按原样分配给m_spColumnInfo,这会将refcount增加到2,然后通常使spResult超出范围,将refcount递减到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函数在每个线程中只能被调用一次,而不能在每个用户函数中被调用。

09-06 18:43