CString
BSTR
SysFreeString(bstrText);
都不用释放的,除非像楼上那样用
CString,_bstr_t,_variant_t
你自己调用::SysAllocString()为BSTR分配的需要调用::SysFreeString().
_bstr_t,_variant_t都是智能指针,会自动释放
BSTR是一种字符串指针,如果你在VC找寻其定义,你会发现它其实是unsigned short*,然而它不能像普通的字符串指针char*一样可以直接赋值,而必须使用SysAllocString来分配,用SysFreeString来释放。
另外,又有两个BSTR的包容类_bstr_t和CComBSTR,它们是为了编程者使用BSTR更加方便,因为在他们的构造函数中都调用了SysAllocString,析构函数调用了SysFreeString,然而使用这两个类时仍然需要特别注意,否则也会导致不可预知的错误。
举例如下:
1.标准用法:
BSTR str = SysAllocString(L”aaa”);
…(可以使用此BSTR变量的范围)
SysFreeString(str);
str = NULL;
需要注意的是当SysFreeString被调用后,最好将此BSTR变量赋为NULL,以防止多次释放,导致释放非法内存空间。
2._bstr_t类型有一个函数叫copy,使用时需要当心,因为它其实调用了SysAllocStringByteLen,所以需要调用者去释放返回的BSTR字符串。
用法如下:
_bstr_t m_state = L"cc";
SysFreeString(str);
str = NULL;
3._bstr_t类型有一个特殊构造函数,其第二个参数是一个bool值,表示是否进行SysAllocString,如果是false,表示直接将此字符指针赋给_bstr_t内部所包容的BSTR,这虽然给使用者带来了更大的灵活性,但却需要使用时更加注意,用法如下:
_bstr_t str2(str1, false);
注意,此时不需要调用SysFreeString,因为_bstr_t的构造函数虽然没有调用SysAllocString,但其析构函数仍然会调用SysFreeString。所以不需要使用者自己去释放了。
4.函数接口传递BSTR或BSTR*的基本规则
·
HRESULT IWebBrowser2::put_StatusText( BSTR bstr );
// shows using the Win32 function
// to allocate memory for the string:
BSTR bstrStatus = ::SysAllocString( L"Some text" );
if (bstrStatus == NULL)
pBrowser->put_StatusText( bstrStatus );
// Free the string:
::SysFreeString( bstrStatus );
//...
·
HRESULT IWebBrowser2::get_StatusText( BSTR FAR* pbstr );
//...
BSTR bstrStatus;
pBrowser->get_StatusText( &bstrStatus );
// shows using the Win32 function
// to freee the memory for the string:
::SysFreeString( bstrStatus );
·
// Example shows using MFC's
// CString::AllocSysString
//...
HRESULT CMyClass::get_StatusText( BSTR * pbstr )
{
// The client is now responsible for freeing pbstr.
return( S_OK );
}
//...
·
5.下面介绍一种比较复杂的情况,利于对问题的深入理解。例如我们现在用到的ICF底层库就有很多类似下面的函数:
void CTestDlg::GetString(BSTR* state)
{
}
其中_bstr_t的copy函数其实调用了SysAllocStringByteLen,所以需要此函数的调用者去进行释放。
释放时需要特别注意,像如下这两种调用方法都是正确的:
(1)
CComBSTR str;
(2)
BSTR str1;
在第一种情况中,CComBSTR被强制转换为BSTR后接受了m_state.copy()返回的字符指针,同时SysAllocStringByteLen被调用了一次,而当其被析构时,SysFreeString被自动调用。所以这种调用方法最终保证了BSTR字符串的正确分配与释放。
在第二中情况中,变量str1接受了m_state.copy()返回的字符指针,同时SysAllocStringByteLen被调用了一次,而在_bstr_t类型变量str2的构造函数中,第二个参数为false,这表示构造函数不再调用SysAllocString,而当其被析构时,SysFreeString被自动调用。所以这种调用方法也是正确的。
而当一个类有一个CComBSTR类型的成员变量时,下面这种调用是错误的:
(3)
因为,它可能被调用多次,每次都执行了SysAllocStringByteLen,但成员变量只会析构一次,所以这样做的问题是会导致内存泄漏,正确的使用方法如下:
(4)
CComBSTR str;
这样使用之所以正确,是因为CComBSTR被赋值时,会调用SysFreeString将其原来的字串释放,并调用SysAllocString,为其分配新的字串。
调用Com接口方法,输入参数中有BSTR参数时的调用方法。
调用Com接口方法,输出参数中有BSTR参数时的调用方法。
函数的参数中有BSTR和BSTR*
STDMETHODIMP BatchMachine::GetParameter(BSTR strName, BSTR *strValue)
{
}