我的泄漏检查程序告诉我此功能有第二次机会异常。
BOOL CADORecordset::SetFieldValue(LPCTSTR lpFieldName, CString strValue)
{
_variant_t vtFld;
if(!strValue.IsEmpty())
vtFld.vt = VT_BSTR;
else
vtFld.vt = VT_NULL;
vtFld.bstrVal = strValue.AllocSysString();
BOOL bret = PutFieldValue(lpFieldName, vtFld);
SysFreeString(vtFld.bstrVal);
return bret;
}
现在,
_variant_t
具有类型BSTR成员(bstrVal
)。我们know需要使用SystemFreeString()
解除BSTR的分配,这是上面的代码中所做的操作,但是由于此BSTR是_variant_t
的成员,该成员具有自己的要清除的析构函数,因此谁应该真正清理在这种情况下的bstrVal
成员?inline _variant_t::~_variant_t() throw()
{
::VariantClear(this);
}
在我看来,这试图再次清理内存,而该内存已经被
SysFreeString()
清除了,从而导致异常? documentation表示清除了变体,但不清楚清除的是什么,是否也释放了bstrVal
?如果我删除呼叫
SysFreeString(vtFld.bstrVal);
,这确实会删除第二次机会异常,但是我真的想知道那是正确的做法,因为文档没有给予足够的信心。 最佳答案
_variant_t
超出范围时会自动清除其数据。您正在手动调用SysFreeString()
,但是之后没有将bstrVal
设置为NULL或将vt
设置为VT_EMPTY
。因此,当variant_t
析构函数调用VariantClear()
清理数据时,它将尝试再次释放bstrVal
并崩溃。
因此,根本不需要手动调用SysFreeString()
。如果您需要手动重置variant_t
,请改用其Clear()
方法:
vtFld.Clear();