C++ CComPtr内存泄漏
我使用crtdbg检测泄漏位置,在调用C++ CComPtr内存泄漏,c++,memory-leaks,visual-leak-detector,C++,Memory Leaks,Visual Leak Detector,我使用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 //a
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();
CComPtr m\u spColumnInfo
CComPtr spResult=新的CDBColumnInfo()//内存泄漏
//另一个逻辑用于将数据设置为spResult
//另一个逻辑用于将数据设置为spResult
//另一个逻辑用于将数据设置为spResult
m_spColumnInfo=静态_转换(spResult.Detach());
spResult.Release();
是否需要对spResult执行任何步骤?您存在内存泄漏,因为您对
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
时,refcount将递减为0,对象将被释放
您根本不应该尝试手动管理refcount。这违背了使用CComPtr
的全部目的
CComPtr<IDBColumnInfo> m_spColumnInfo;
...
{
CComPtr<CDBColumnInfo> spResult = new CDBColumnInfo();
//set data to spResult
m_spColumnInfo = spResult;
}
CComPtr m_spColumnInfo;
...
{
CComPtr spResult=新的CDBColumnInfo();
//将数据设置为spResult
m_spColumnInfo=spResult;
}
另外,另一方面,您的函数根本不需要调用
CoInitialize()
和CoUninitialize()
!您需要从函数中删除这些调用(特别是因为您的函数在退出函数的大多数代码路径中甚至不调用coninitialize()
)。这些调用不是您的函数的责任。调用函数的线程负责决定如何为自己初始化COM。每个线程只能调用一次这些COM函数,而不是每个用户函数。为什么需要spResult.Detach()
?为什么不这样做:m\u spColumnInfo=static\u cast(spResult)
?我有一段时间没有使用CComPtr
,但是操作符说操作符=
会增加引用计数,所以通过使用Detach
,我认为当您尝试转移所有权时,您将得到一个额外的AddRef
,而没有相应的释放。尝试用我建议的行替换spResult.Detach()
。@jamesdlin在查看实际代码后,我在该函数中遇到异常:您根本不需要删除spResult
。另外,我会将spResult
声明为CComPtr
,然后完全摆脱静态转换。@jamesdlin我改为CComPtr spResult=new-cdbcolumnfo()
但是具有一些功能的CDBColumnInfo
无法通过spResult
访问。ExHRESULT CDBColumnInfo::GetField(LPCOLESTR fieldName)