如何清除_variant_t



我的泄漏检查器告诉我在这个函数中有第二次机会异常。

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(。我们知道BSTR需要使用SystemFreeString()来取消分配,这是上面代码中所做的,但由于这个BSTR是_variant_t的成员,它有自己的析构函数来清理,在这种情况下,谁应该真正清理bstrVal成员?

inline _variant_t::~_variant_t() throw()
{
    ::VariantClear(this);
}

在我看来,这似乎试图再次清理已经被SysFreeString()清理过的内存,导致异常?文件说它清除了变体,但不清楚它到底清除了什么,它也释放了bstrVal吗?

如果我删除调用SysFreeString(vtFld.bstrVal);,这确实会删除第二次机会异常,但我真的想知道这是正确的做法,因为文档没有提供足够的信心。

_variant_t在超出范围时自动清理其数据。您正在手动调用SysFreeString(),但之后不会将bstrVal设置为NULL或将vt设置为VT_EMPTY。因此,当variant_t析构函数调用VariantClear()来清理数据时,它试图再次释放bstrVal并崩溃。

因此,根本不要手动调用SysFreeString()。如果您需要手动重置variant_t,请使用其Clear()方法:

vtFld.Clear();

variant_t拥有其数据并使用VariantClear()函数进行清理:

该函数通过将vt字段设置为vt_EMPTY来清除VARIANTARG。VARIANTARG的当前内容首先发布如果vtfield是VT_BSTR,则字符串被释放。如果vtfield为VT_DISPATCH,则对象将被释放。如果vt字段设置了vt_ARRAY位,则阵列将被释放。

CCD_ 22是一个负责内存管理的包装器。类似于管理BSTR_bstr_t;他们合作得最好。与其手动设置vt字段和bstrVal值,不如使用variant_t构造函数或operator=。CCD_ 29将分配CCD_ 30所有权并将其传递给CCD_ 31。我不记得使用它的详细信息了。只需在MSDN上查找详细信息即可。

相关内容

  • 没有找到相关文章

最新更新