大家看看下边的代码有什么问题?

zzyx 2003-08-07 03:27:40
前些天遇到一个问题,俺试验了很长时间才解决,但还不清楚为什么。

使用一个类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;
}
...全文
38 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
zzyx 2003-08-11
  • 打赏
  • 举报
回复
呵呵,不管是可以,但看上去够烦的
结账了
lygfqy 2003-08-08
  • 打赏
  • 举报
回复
myAdo.Open();//***//
IDispatch* pDisp=NULL;
myAdo.GetConn()->QueryInterface (IID_IDispatch,(void**)&pDisp);//***//
//...
带星的两行代码互换一下如何?
zzyx 2003-08-08
  • 打赏
  • 举报
回复
这个问题有那么难吗?dx们伸伸手吧!
arxing 2003-08-08
  • 打赏
  • 举报
回复
呵呵,那就证明是BoundsChecker错误了,别管它好啦。
zzyx 2003-08-08
  • 打赏
  • 举报
回复
题外话:
这几天回来发现好像csdn,尤其是这个版里的人气非常不旺盛啊!
以前常见到的几个dx也不知道哪去了
回答问题的也不多,就算答了问题,结账的也很少
哎....
zzyx 2003-08-08
  • 打赏
  • 举报
回复
呵呵,arxing终于出现了。

每次调用test()的时候
检查了pDisp->Release的返回值,引用计数是1,因为m_spADOCN 还没有释放,
看上去似乎没有错误

只是最后BoundsChecker报告说计数错误。
难道真的是BoundsChecker这个家伙犯傻?

至于说用_ConnectionPtr作为返回值,是当时俺偷懒,代码量比用原生指针少多了
arxing 2003-08-08
  • 打赏
  • 举报
回复
虽然你的代码很不好,因为很少采用_ConnectionPtr作返回值的,就像通常采用LPCTSTR作返回值而不用CString一样。
但是你确信它内存泄漏吗?我从来不相信各种内存泄漏检查工具,还是靠自己检查好一些。AddRef,Release不是返回一个引用计数吗?你应该用这个返回值来确认是否内存泄漏。
我粗略一看没有啥泄漏,你先用检查一下Release()的返回值再说吧。
zzyx 2003-08-07
  • 打赏
  • 举报
回复
其实,跟踪代码就发现,myAdo.GetConn()->DoSomething
在返回智能指针的时候是自动执行了AddRef,并在调用完毕时候自动进行了Release的,

另外,实际使用中还发现,如果我的例子中不是调用QueryInterface,而是如Execute,CommandTimeout之类的普通方法的话,是不会出现这个问题的

如果在main函数中只执行test一次,那么有_Connection对象有一个引用计数没有释放,
如果执行两次,则有4个引用计数没有释放。

3,245

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧