Col*_*ond 4 c++ mfc memory-leaks
我被告知有几个工具,下面的代码是泄漏内存,但我们不能为我们的生活看到在哪里:
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;
}
Run Code Online (Sandbox Code Playgroud)
我们假设它与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;
}
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)
根据工具(GlowCode),这不再泄漏,但我担心在将字段分配给CString后在fieldValue上使用SysFreeString.它似乎运行,但我知道这并不表示内存损坏是免费的!
您必须释放为BSTR分配的内存.
见文章
哦,你必须在将VARIANT的bstr值赋给CString之前进行分离
strFieldValue = olevar.detach().bstrVal;
Run Code Online (Sandbox Code Playgroud)
然后确保您的CString对象及时被正确销毁.
| 归档时间: |
|
| 查看次数: |
2362 次 |
| 最近记录: |