gpt4 book ai didi

c++ - 关于 MFC 库中的 _variant_t 类型

转载 作者:行者123 更新时间:2023-11-28 06:58:55 27 4
gpt4 key购买 nike

在我的 MFC (VC2010 SP1) 项目中,我广泛使用第三方库在数据库中写入一些数据。这个库很旧(我发现它是为 VS2005 编译的)并使用 _variant_t 来处理数据。

无论如何,在特定情况下我会出现奇怪的行为,我会尝试解释它:

// .h
struct myData
{
blastuff
CString strMyCode;
};

class MyClass
{
protected:
myData m_Foo;
};

// .cpp
// In OnInitDialog:
//...
TrdPartRecordset *pRS;

//...
pRS->GetFieldValue( _T("MyDBColumn"), m_Foo.strMyCode );

现在,我完成我的工作,当用户按下 OK 时,是时候保存到数据库了,问题就在这里开始:

 // In OnOK
TrdPartRecordset *pRS;
//...
pRS->SetFieldValue( _T("MyDBColumn"), m_Foo.strMyCode );

问题:如果我不修改m_Foo.strMyCode,我没有任何问题。如果我修改它呢?好吧,如果 m_Foo.strMyCode 确实NOT 包含任何 数字,仍然没有问题。相反,当我有一个数字时,我得到一个讨厌的错误:

Unhandled exception at 0x77772d37 in Mosaico.exe: 0xC0000005: Access violation reading location 0x9d7077b7.

这是试图读取已删除的位置。我检查了 watch 中的 m_Foo,它是正确有效的,所以我深入研究了库源代码:

BOOL TrdPartyRecordset::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;
}

它发生的是 vtFld 在 SysFreeString 之前有效,并且在它之后被销毁(我可以看到它通过调试器逐步进行),但只有当我有数字进入 strValue 时。当 strValue 是纯字母顺序时,不会发生这种情况。

我在 Internet 上搜索了一下,发现当您双重释放资源时会发生这种错误,所以我注释掉了 SysFreeString 并且炸药爆炸了:不再发生崩溃。

无论如何,他是一个比我更好的程序员,所以我猜如果他放那个 SysFreeString 是有他的理由的,而且,这是我程序中这个机制崩溃的唯一部分。

我的问题是:注释掉 SysFreeString 后我会失去内存吗?另一个:你们有更好的解决方案吗?

最佳答案

原因很简单:内存被释放了两次!

_variant_t 有一个析构函数。将类型设置为 VT_BSTR。您还会看到指针并键入 VT_BSTR

在您调用的函数之后,您再次释放内存,析构函数执行相同的操作。

代码应该是这样的:

_variant_t vtFld;
if(!strValue.IsEmpty())
vtFld = strValue;
else
vtFld.vt = VT_NULL;
return PutFieldValue(lpFieldName, vtFld);

关于c++ - 关于 MFC 库中的 _variant_t 类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22791678/

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