我使用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是否需要执行任何步骤?
答案 0 :(得分:1)
内存泄漏,因为您没有正确管理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函数在每个线程中只能被调用一次,而不能在每个用户函数中被调用。