关闭

忍不住还是要发篇文章:关于VC6中(VARIANT)BSTR传入传出发生RtlSizeHeap(user breakpoint at address)的问题

标签: userfunctionstringpointersvariablesobject
2619人阅读 评论(0) 收藏 举报
分类:

As it turns out, I was able to determine why I was getting this RTLSizeHeap problem. Being a novice to COM and ATL, I had a class that stored a string (_bstr_t) value. As you would expect, I had the normal get_ and put_ functions to operate on the member. The problem was, my get_ did not send back a copy of the string held onto by the _bstr_t member that I had set up. All I did was assign it (thinking the operator = function actually makes a copy). Since I was using smart pointers, I had the result of the get_ function assigned to another _bstr_t. The problem...both _bstr_t values were looking at the same memory. So no problem would occur when the first object goes out of scope as the first _bstr_t frees the memory it was holding, but when the second object would go out of scope...bam RtlSizeHeap problem - since the second _bstr_t was still pointing to memory that was now freed. To solve this, my get_ function was changed to:

STDMETHODIMP CSomeClass::get_m_sToTime(BSTR *pVal)
{
AFX_MANAGE_STATE(AfxGetAppModuleState())
if (pVal)
*pVal = bstrtToTime.copy();
return S_OK;
}

Summary - RtlSizeHeap is definitely not lying - Most certainly this error is the result of BSTRs and _bstr_t variables not being handled appropriately. Double and tripple check your code - It took me a long time to find this!

Hope this helps!
Dan
//以上是老外的说法,有道理

我的问题:在external(自定义浏览器控件)中要向javascript中输出一个字符串,我原来的做法是if(pVarResult) *pVarResult=CComVariant(_T"myOutString");而CComVariant会自动回收heap上的空间。所以问题出现在=号上。*pVarResult是一个VARIANT结构变量,程序中又没有重载该类型的=操作,于是bstrVal指向CComVariant中的bstrVal,而CComVariant自动回收了,因此,js中的接收变量的值便不可预料,并且,在js退出该变量的生存空间时,要回收该变量的空间,于是出错。这个问题在MSDN中说得已经很明白,可惜没想到,走了一大堆弯路。

当创建 BSTR 并在 COM 对象之间传递它们时,必须小心地处理它们所使用的内存以避免内存泄漏。当 BSTR 停留在接口中时,在完成其使用后必须释放出它的内存。但是,如果 BSTR 传递出了接口,那么接收对象将负责它的内存管理。
一般情况下,分配和释放分配给 BSTR 的内存的规则如下:
当调用进来一个需要 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)
   return E_OUTOFMEMORY;

pBrowser->put_StatusText( bstrStatus );
// Free the string:
::SysFreeString( bstrStatus );
//...
当调用进来一个返回 BSTR 的函数时,必须自己来释放字符串。例如:
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 );
当实现返回 BSTR 的函数时,请分配字符串,但不要释放它。接收函数会释放内存。例如:
// Example shows using MFC's
// CString::AllocSysString

//...
HRESULT CMyClass::get_StatusText( BSTR * pbstr )
{

   try
   {
      //m_str is a CString in your class
      *pbstr = m_str.AllocSysString( );
      }
   catch (...)
   {
      return E_OUTOFMEMORY;
   }

// The client is now responsible for freeing pbstr.
return( S_OK );
}
//...

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:887846次
    • 积分:10483
    • 等级:
    • 排名:第1581名
    • 原创:152篇
    • 转载:318篇
    • 译文:33篇
    • 评论:77条
    最新评论