我使用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函数在每个线程中只能被调用一次,而不能在每个用户函数中被调用。