gpt4 book ai didi

c++ - 如何正确地将 _bstr_t 重置为 `NULL`

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:23:31 25 4
gpt4 key购买 nike

在下面的代码片段中(循环的简化场景)

_bstr_t original(OLESTR("MyString")); // ref-count = 1
_bstr_t another;
another = original; // ref-count = 2
// do something with another
another.Assign(NULL); // expected: ref-count = 1, and another = NULL
// reset another to NULL before doing other operations

another.Assign(NULL) 之后我期望的是:

  • SysFreeString() 未被调用
  • 另一个设置为NULL
  • ref-count 减为 1
  • originalref count=1 和现有的 BSTR 内容。

发生了什么:

  • SysFreeString()anotheroriginal 的底层 BSTR 调用
  • 另一个设置为NULL
  • original 的引用计数保持为 2

another.Assign(NULL) 似乎为 originalanother 释放了底层 BSTR。< br/>我们遇到了意外崩溃,因为在编码期间我认为 _bstr_t::Assign() 会减少引用计数,而不是直接释放 BSTR

如何在不影响 original 的情况下正确地将 another 重置为 NULL

请从 VC++ 6 中找到 Assign 的以下实现。

// assignment operator copies internal data and increases reference count
inline _bstr_t& _bstr_t::operator=(const _bstr_t& s) throw()
{
const_cast<_bstr_t*>(&s)->_AddRef();
_Free();
m_Data = s.m_Data;

return *this;
}
// but _bstr_t::Assign() calls _bstr_t::Data_t::Assign()
// without touching ref count
inline void _bstr_t::Assign(BSTR s) throw(_com_error)
{
if (m_Data != NULL) {
m_Data->Assign(s);
}
else {
m_Data = new Data_t(s, TRUE);
if (m_Data == NULL) {
_com_issue_error(E_OUTOFMEMORY);
}
}
}
// it calls _bstr_t::Data_t::_Free() instead of _bstr_t::_Free() !
inline void _bstr_t::Data_t::Assign(BSTR s) throw(_com_error)
{
_Free();
if (s != NULL) {
m_wstr = ::SysAllocStringByteLen(reinterpret_cast<char*>(s),
::SysStringByteLen(s));
}
}
// this _Free() straight away deallocates the BSTR!
inline void _bstr_t::Data_t::_Free() throw()
{
if (m_wstr != NULL) {
::SysFreeString(m_wstr);
}

if (m_str != NULL) {
delete [] m_str;
}
}
// properly decrements ref count
inline void _bstr_t::_Free() throw()
{
if (m_Data != NULL) {
m_Data->Release();
m_Data = NULL;
}
}

最佳答案

_bstr_t::Assign() 的实现已更新,如 Igor Tandetnik 所述在他的 comment .

这是 VS2010 中的实现,它按预期工作:

inline void _bstr_t::Assign(BSTR s) 
{
_COM_ASSERT(s == NULL || m_Data == NULL || m_Data->GetWString() != s);

if (s == NULL || m_Data == NULL || m_Data->GetWString() != s)
{
_Free();

m_Data = new Data_t(s, TRUE);
if (m_Data == NULL) {
_com_issue_error(E_OUTOFMEMORY);
}
}
}

关于c++ - 如何正确地将 _bstr_t 重置为 `NULL`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17804546/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com