避免BSTR内存泄漏

SimonXie 2010-01-08 01:32:41
加精
很多人在使用BSTR的时候都会遇到内存泄漏的问题,下面我总结了一下,严格按照下面的做法可以避免内存泄漏,供参考.

先说COM函数内部的做法
1、参数传出值[out]按如下:
HRESULT GetName([out] BSTR* bstrName)
{
ASSERT(NULL == bstrName);//确保传入的指针为空;
*bstrName = _T("test");
return S_OK;
}

2、参数为传入传出值[in, out]按如下:
HRESULT GetName([in, out] BSTR* bstrName)
{
CComBSTR oldName = bstrName;
SysFreeString(bstrName);//必须先释放原来字符串
*bstrName = _T("test");
return S_OK;
}

3、作为函数返回值,按如下:
BSTR GetName()
{
CString csName = _T("test");
return csName.AllocSysString();
}

调用者部份:
1如果使用CComBSTR对象作为参数时,不要对此对象初始化;
2对传没啥要求;
关键是3,很容易造成内存泄漏,例如如下的调用:
TRACE("%s", GetName());
上面这样就会造成内存泄漏。正确的方法应该是如下:
BSTR bstrName = GetName();
TRACE("%s", bstrName);
SysFreeString(bstrName);//释放返回字符串

因此,建议大家尽量避免使用3的形式
...全文
2146 86 打赏 收藏 转发到动态 举报
写回复
用AI写文章
86 条回复
切换为时间正序
请发表友善的回复…
发表回复
youngvc05 2011-01-18
  • 打赏
  • 举报
回复
BSTR是得小心使用
SurgePing 2011-01-18
  • 打赏
  • 举报
回复
在编写COM组件时,对于BSTR字符串,我们应遵循这个原则:谁使用,谁释放。注意是谁使用,并不是说声明与释放要放在一起。
而CCOMBSTR和_bstr_t都是智能指针,在一个对象释放的时候就会自己释放内存。所以这两个类型是用的最多的。
而CCOMBSTR和_bstr_t也有些区别。如用的场合(一般)和转换的细微差别;
一般_bstr_t用在数据库编程上,而且他跟C++的CString可以直接转换的;而CCOMBSTR则就用在别的地方。

LZ代码上就是有些结构上的错误,可能是写快了,呵呵
yuyifish 2011-01-05
  • 打赏
  • 举报
回复
错误的太离谱了,首先保证传入的指针为空,紧接着下面一行就解引用,NULL指针怎么解引用???
这不扯嘛,就没人发现这个问题?
youngwolf 2010-11-05
  • 打赏
  • 举报
回复
分配和释放BSTR一直都有很详尽的MSDN:
http://msdn.microsoft.com/zh-cn/library/cc485262(VS.71).aspx

不知道本篇文章是如何被推荐的?
youngwolf 2010-11-05
  • 打赏
  • 举报
回复
我不相信COM标准是这样规定的!

*bstrName = _T("test");
这种用法第一次见,不好意思!
lnqq430 2010-11-04
  • 打赏
  • 举报
回复
good, I'll try
zipper9527 2010-10-22
  • 打赏
  • 举报
回复
这样一贴子也有这么多人回,受不了
gw_net 2010-04-07
  • 打赏
  • 举报
回复
COM method内外都用_bstr_t或CComBSTR就行了
tj_swjtu 2010-04-07
  • 打赏
  • 举报
回复
good
jmynyq 2010-04-07
  • 打赏
  • 举报
回复
顶 学习
lijianli9 2010-04-06
  • 打赏
  • 举报
回复
哈哈,学习了,一直对COM有点怕呀,
xuxian02092213 2010-03-02
  • 打赏
  • 举报
回复
顶下,
~~~~~~~~~~~~~~~~
gooore 2010-03-02
  • 打赏
  • 举报
回复
来学习下...............
miffy0533 2010-03-01
  • 打赏
  • 举报
回复
来学习下...............
hslinux 2010-02-25
  • 打赏
  • 举报
回复
路过~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
skyfree 2010-02-21
  • 打赏
  • 举报
回复
一般用_bstr_t 智能指针
mc_ 2010-02-21
  • 打赏
  • 举报
回复
哦,路过。。。。谢谢分享经验
青稞 2010-02-10
  • 打赏
  • 举报
回复
学习了,我一直用的_bstr_t,但里面具体是怎么实现的,我没有去研究过,受教了..
AutoWalk 2010-02-10
  • 打赏
  • 举报
回复
引用 9 楼 jameshooo 的回复:
顶一下。

提醒一点,1、3有点不符合规范,当使用OUT参数时,不能直接使用:
*bstrName = _T("test");
这种做法当客户端释放BSTR时将会报错,因为 "test" 并不是通过 SysAllocString 分配的,必须改成:
*bstrName = ::SysAllocString(L"test");

客户端在很多情况下并不直接使用BSTR,而是使用了封装类 CComBSTR 或者 _bstr_t,大概是这样用的:
CComBSTR bstr;
GetName(&bstr);
当 bstr 生命期结束时,CComBSTR的析构函数会自动调用 SysFreeString,_bstr_t 也是一样的。在跨语言使用时尤其要注意规范,否则出错都不知道原因。


受教
ltq678 2010-02-10
  • 打赏
  • 举报
回复
谢谢lz

学习了
加载更多回复(66)

3,245

社区成员

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

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