gpt4 book ai didi

c++ - 这个C++的内存泄漏在哪里?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:26:05 24 4
gpt4 key购买 nike

我被告知以下代码正在泄漏内存的几个工具,但我们无法在我们的生活中看到哪里:

HRESULT CDatabaseValues::GetCStringField(ADODB::_RecordsetPtr& aRecordset, CString& strFieldValue,
const char* strFieldName, const bool& bNullAllowed)
{
HRESULT hr = E_FAIL;

try
{
COleVariant olevar;
olevar = aRecordset->Fields->GetItem(_bstr_t(strFieldName))->Value;
if (olevar.vt == VT_BSTR && olevar.vt != VT_EMPTY)
{
strFieldValue = olevar.bstrVal;
hr = true;
}
else if ((olevar.vt == VT_NULL || olevar.vt == VT_EMPTY) && bNullAllowed)
{
//ok, but still did not retrieve a field
hr = S_OK;
strFieldValue = "";
}
}
catch(Exception^ error)
{
hr = E_FAIL;
MLogger::Write(error);
}
return hr;
}

我们假设它与 olevar 变体有关,因为泄漏的大小与从记录集中返回的字符串的大小相匹配。

我已经尝试了 olevar.detach() 和 olevar.clear(),两者都没有效果,所以如果这是原因,我该如何释放可能在 GetItem 中分配的内存。如果这不是原因,那是什么?

编辑

我阅读了 Ray 推荐的文章以及与之相关的评论,然后尝试:

HRESULT CDatabaseValues::GetCStringField(ADODB::_RecordsetPtr& aRecordset, CString& strFieldValue,
const char* strFieldName, const bool& bNullAllowed)
{
HRESULT hr = E_FAIL;

try
{
COleVariant* olevar = new COleVariant();
_bstr_t* fieldName = new _bstr_t(strFieldName);
*olevar = aRecordset->Fields->GetItem(*fieldName)->Value;
if (olevar->vt == VT_BSTR && olevar->vt != VT_EMPTY)
{
strFieldValue = olevar->bstrVal;
hr = true;
}
else if ((olevar->vt == VT_NULL || olevar->vt == VT_EMPTY) && bNullAllowed)
{
//ok, but still did not retrieve a field
hr = S_OK;
strFieldValue = "";
}
delete olevar;
delete fieldName;
}
catch(Exception^ error)
{
hr = E_FAIL;
MLogger::Write(error);
}
return hr;
}

主要区别在于 olevariant 和 bstr 现在已明确创建和销毁。

这大约使泄漏量减少了一半,但这里仍有一些东西在泄漏。

解决方案?

看了 Ray 关于使用 Detach 的建议,我想到了这个:

HRESULT CDatabaseValues::GetCStringField(ADODB::_RecordsetPtr& aRecordset, CString& strFieldValue,
const char* strFieldName, const bool& bNullAllowed)
{
HRESULT hr = E_FAIL;

try
{
COleVariant olevar;
_bstr_t fieldName = strFieldName;
olevar = aRecordset->Fields->GetItem(fieldName)->Value;

if (olevar.vt == VT_BSTR && olevar.vt != VT_EMPTY)
{
BSTR fieldValue = olevar.Detach().bstrVal;
strFieldValue = fieldValue;
::SysFreeString(fieldValue);
hr = true;
}
else if ((olevar.vt == VT_NULL || olevar.vt == VT_EMPTY) && bNullAllowed)
{
//ok, but still did not retrieve a field
hr = S_OK;
strFieldValue = "";
}
::SysFreeString(fieldName);
}
catch(Exception^ error)
{
hr = E_FAIL;
MLogger::Write(error);
}
return hr;
}

根据工具 (GlowCode),这不再泄漏,但我担心在将 SysFreeString 分配给 CString 后对 fieldValue 使用 SysFreeString。它似乎在运行,但我知道这并不表示没有内存损坏!

最佳答案

您必须释放分配给 BSTR 的内存。

参见 article

哦,在将 VARIANT 的 bstr 值分配给 CString 之前,您必须进行分离

strFieldValue = olevar.detach().bstrVal;

然后确保您的 CString 对象及时被正确销毁。

关于c++ - 这个C++的内存泄漏在哪里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1237768/

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