0

我使用 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 是否需要执行任何步骤?

4

1 回答 1

1

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

当你初始化spResult时,对象的 refcount 被初始化为 1。当你调用spResult.Detach()时,对象的 refcount 仍然是 1,因为Detach()它并没有递减。当分离的指针被分配给m_spColumnInfo时,对象的 refcount 增加到 2。当m_spColumnInfo稍后释放时,它将对象的重新计数减少到 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 函数应该每个线程只调用一次,而不是每个用户函数。

于 2019-05-03T09:21:37.250 回答