描述:
前些天遇到一个问题,俺试验了很长时间才解决,但还不清楚为什么。
使用一个类CMyADO来封装ADO连接对象,ADO的连接对象使用智能指针
在程序的不同地方,不同线程中来调用CMyADO的 GetConn方法
运行后发现,引用计数总是错的(使用BoundsChecker),多出来许多。
最后,俺把智能指针换成原生指针解决了这个问题。但不知道为什么会这样。
dx们出手看看,俺的代码是否有问题?
实际的使用环境比这个复杂得多,抽象出来代码如下……问题现象依然。
class CMyADO
{
public:
_ConnectionPtr GetConn();
BOOL CloseAndFree();
BOOL Open();
CMyADO();
virtual ~CMyADO();
_ConnectionPtr m_spADOCN;
};
BOOL CMyADO::Open()
{
HRESULT hr;
_bstr_t cn=L"Provider=SQLOLEDB.1;....";
hr=m_spADOCN.CreateInstance (L"ADODB.Connection");
m_spADOCN->Open(cn,"","",adConnectUnspecified);
return true;
}
BOOL CMyADO::CloseAndFree()
{
m_spADOCN->Close;
m_spADOCN.Release ();
return true;
}
_ConnectionPtr CMyADO::GetConn()
{
return m_spADOCN;
}
//****************************************
int test()
{
CMyADO myAdo;
myAdo.Open();
IDispatch* pDisp=NULL;
myAdo.GetConn()->QueryInterface (IID_IDispatch,(void**)&pDisp);
//...
pDisp->Release ();
myAdo.CloseAndFree ();
return 0;
}
int main(int argc, char* argv[])
{
CoInitialize(NULL);
test();
CoUninitialize();
return 0;
}
解决方案1:
虽然你的代码很不好,因为很少采用_ConnectionPtr作返回值的,就像通常采用LPCTSTR作返回值而不用CString一样。
但是你确信它内存泄漏吗?我从来不相信各种内存泄漏检查工具,还是靠自己检查好一些。AddRef,Release不是返回一个引用计数吗?你应该用这个返回值来确认是否内存泄漏。
我粗略一看没有啥泄漏,你先用检查一下Release()的返回值再说吧。
myAdo.Open();//***//
IDispatch* pDisp=NULL;
myAdo.GetConn()->QueryInterface (IID_IDispatch,(void**)&pDisp);//***//
//...
带星的两行代码互换一下如何?