kamaldev k r
asked on
ADODB Command memory leak on execute()
I am getting memory leak on line paramcmd->Execute(NULL, NULL, NULL);. Just commenting the line give no leak. Any further resource need to free on invoking execute(). SQL server 2017
HRESULT CEpks870psDB::ReadPointParameters(const std::vector<std::wstring>& PointNames, std::vector<int>& ParamIds, const std::vector<std::wstring>& ParamNames, std::vector<db_param>& param_details)
{
DWORD start_time = GetTickCount();
log(L_PARAM, "%s: enter", __FUNCTION__);
param_details.resize(PointNames.size());
_CommandPtr paramcmd;
paramcmd.CreateInstance(__uuidof(Command));
paramcmd->ActiveConnection = m_pADOConnection;
paramcmd->CommandType = adCmdText;
paramcmd->Prepared = true;
paramcmd->CommandTimeout = 30;
// should return the same result as V_PointAttribute view in SQL.
paramcmd->CommandText = L"SELECT TOP 1 AttributeIGDAAccess,IsStrValue,IsNumValue,IsIntValue, "
L"ISNULL(StrValue,DefaultStrValue) AS StrValue,ISNULL(NumValue, DefaultNumValue) AS NumValue,ISNULL(IntValue, DefaultIntValue) AS IntValue, "
L"AttributeDataSource,AttributeDataSourceAttribute, "
L"MinNumValue,MaxNumValue,AttributeICONFIGAccess,a.AttributeName,p.PointDefinitionTypeID,a.AttributeDataType,a.AttributeDataType_2 "
L"FROM Point p INNER JOIN PointTypeAttribute pta ON "
L"p.PointID=? AND pta.AttributeID=? AND p.PointDefinitionTypeID=pta.PointDefinitionTypeID "
L"LEFT OUTER JOIN PointAttribute pa ON "
L"p.PointID=pa.PointID AND pta.AttributeID=pa.AttributeID "
L"INNER JOIN Attribute a "
L"ON pta.AttributeID=a.AttributeID";
_ParameterPtr pcpointid = paramcmd->CreateParameter(L"PointID", adInteger, adParamInput, 0, _variant_t(1));
paramcmd->Parameters->Append(pcpointid);
_ParameterPtr pcparamname = paramcmd->CreateParameter(L"ParamID", adInteger, adParamInput, 0, _variant_t(1));
paramcmd->Parameters->Append(pcparamname);
for (int i = 0; i < PointNames.size(); i++)
{
int pointid = 0;
int createtime = 0;
GetPointId(PointNames[i], pointid, createtime);
param_details[i].point_createtime = createtime;
if (pointid == 0)
{
param_details[i].Default.vt = VT_ERROR;
param_details[i].Default.scode == M4_INV_POINT;
continue;
}
param_details[i].Default.vt = VT_ERROR;
param_details[i].Default.scode = M4_INV_PARAMETER;
int paramid = 0;
if (ParamIds.size()) paramid = ParamIds[i];
if (paramid == 0)
{
paramid=GetParameterID(ParamNames[i]);
}
if (paramid == 0)
{
continue;
}
paramcmd->Parameters->Item[L"PointID"]->Value = pointid;
paramcmd->Parameters->Item[L"ParamID"]->Value = paramid;
try
{
if (m_pADORecordSet->State == adStateOpen)
m_pADORecordSet->Close();
m_pADORecordSet = paramcmd->Execute(NULL, NULL, NULL);
if (m_pADORecordSet->State == adStateOpen &&
!(m_pADORecordSet->BOF) &&
!(m_pADORecordSet->adoEOF))
{
param_details[i].sIGDAAccess = m_pADORecordSet->Fields->GetItem(short(0))->Value;
param_details[i].sSourceSystem = m_pADORecordSet->Fields->GetItem(short(7))->Value;
param_details[i].sSourceAtt = m_pADORecordSet->Fields->GetItem(short(8))->Value;
const bool isstr = m_pADORecordSet->Fields->GetItem(short(1))->Value.intVal != 0;
const bool isnum = m_pADORecordSet->Fields->GetItem(short(2))->Value.intVal != 0;
const bool isint = m_pADORecordSet->Fields->GetItem(short(3))->Value.intVal != 0;
_variant_t val;
if (isstr)
{
val = m_pADORecordSet->Fields->GetItem(short(4))->Value;
}
else if (isnum)
{
val = m_pADORecordSet->Fields->GetItem(short(5))->Value;
}
else if (isint)
{
val = m_pADORecordSet->Fields->GetItem(short(6))->Value;
}
_variant_t vDTValue = m_pADORecordSet->Fields->GetItem(short(14))->Value;
_variant_t vDT2Value = m_pADORecordSet->Fields->GetItem(short(15))->Value;
VariantValueCopy(¶m_details[i].Default, val, vDTValue, vDT2Value);
if (val.vt == VT_ERROR)
{
// VariantValueCopy checks vDT2Value to see if val.vt can be converted to GDAITEM.
// If it fails here then should check VariantValueCopy, SQL db and the conversion code to GDAITEM.
log(L_ERROR, "%s: pnt=%d prm=%d fail to convert err=%x", __FUNCTION__, pointid, paramid, val.scode);
}
param_details[i].vMinValue = m_pADORecordSet->Fields->GetItem(short(9))->Value;
if (param_details[i].vMinValue.vt != VT_NULL)
{
param_details[i].vMinValue.ChangeType(VT_R4);
}
param_details[i].vMaxValue = m_pADORecordSet->Fields->GetItem(short(10))->Value;
if (param_details[i].vMaxValue.vt != VT_NULL)
{
param_details[i].vMaxValue.ChangeType(VT_R4);
}
param_details[i].sICONFIGAccess = m_pADORecordSet->Fields->GetItem(short(11))->Value;
param_details[i].AttributeName= _bstr_t(m_pADORecordSet->Fields->GetItem(short(12))->Value);
param_details[i].lOrdinal= m_pADORecordSet->Fields->GetItem(short(13))->Value;
dbcache::param.add(param_details[i].AttributeName, 0, paramid);
m_pADORecordSet->Close();
}
else
{
param_details[i].AttributeName = CA2W(dbcache::param.get_name(paramid).c_str());
}
}
catch (_com_error &e)
{
log(L_LOG, "%s: exception caught %S", __FUNCTION__, e.ErrorMessage());
}
}
paramcmd->ActiveConnection = NULL;
paramcmd = NULL;
DWORD took = GetTickCount() - start_time;
log(L_LOG, "%s: exit count=%d took=%dms", __FUNCTION__, PointNames.size(), took);
return S_OK;
}
HRESULT CEpks870psDB::ReadPointParameters(const std::vector<std::wstring>& PointNames, std::vector<int>& ParamIds, const std::vector<std::wstring>& ParamNames, std::vector<db_param>& param_details)
{
DWORD start_time = GetTickCount();
log(L_PARAM, "%s: enter", __FUNCTION__);
param_details.resize(PointNames.size());
_CommandPtr paramcmd;
paramcmd.CreateInstance(__uuidof(Command));
paramcmd->ActiveConnection = m_pADOConnection;
paramcmd->CommandType = adCmdText;
paramcmd->Prepared = true;
paramcmd->CommandTimeout = 30;
// should return the same result as V_PointAttribute view in SQL.
paramcmd->CommandText = L"SELECT TOP 1 AttributeIGDAAccess,IsStrValue,IsNumValue,IsIntValue, "
L"ISNULL(StrValue,DefaultStrValue) AS StrValue,ISNULL(NumValue, DefaultNumValue) AS NumValue,ISNULL(IntValue, DefaultIntValue) AS IntValue, "
L"AttributeDataSource,AttributeDataSourceAttribute, "
L"MinNumValue,MaxNumValue,AttributeICONFIGAccess,a.AttributeName,p.PointDefinitionTypeID,a.AttributeDataType,a.AttributeDataType_2 "
L"FROM Point p INNER JOIN PointTypeAttribute pta ON "
L"p.PointID=? AND pta.AttributeID=? AND p.PointDefinitionTypeID=pta.PointDefinitionTypeID "
L"LEFT OUTER JOIN PointAttribute pa ON "
L"p.PointID=pa.PointID AND pta.AttributeID=pa.AttributeID "
L"INNER JOIN Attribute a "
L"ON pta.AttributeID=a.AttributeID";
_ParameterPtr pcpointid = paramcmd->CreateParameter(L"PointID", adInteger, adParamInput, 0, _variant_t(1));
paramcmd->Parameters->Append(pcpointid);
_ParameterPtr pcparamname = paramcmd->CreateParameter(L"ParamID", adInteger, adParamInput, 0, _variant_t(1));
paramcmd->Parameters->Append(pcparamname);
for (int i = 0; i < PointNames.size(); i++)
{
int pointid = 0;
int createtime = 0;
GetPointId(PointNames[i], pointid, createtime);
param_details[i].point_createtime = createtime;
if (pointid == 0)
{
param_details[i].Default.vt = VT_ERROR;
param_details[i].Default.scode == M4_INV_POINT;
continue;
}
param_details[i].Default.vt = VT_ERROR;
param_details[i].Default.scode = M4_INV_PARAMETER;
int paramid = 0;
if (ParamIds.size()) paramid = ParamIds[i];
if (paramid == 0)
{
paramid=GetParameterID(ParamNames[i]);
}
if (paramid == 0)
{
continue;
}
paramcmd->Parameters->Item[L"PointID"]->Value = pointid;
paramcmd->Parameters->Item[L"ParamID"]->Value = paramid;
try
{
if (m_pADORecordSet->State == adStateOpen)
m_pADORecordSet->Close();
m_pADORecordSet = paramcmd->Execute(NULL, NULL, NULL);
if (m_pADORecordSet->State == adStateOpen &&
!(m_pADORecordSet->BOF) &&
!(m_pADORecordSet->adoEOF))
{
param_details[i].sIGDAAccess = m_pADORecordSet->Fields->GetItem(short(0))->Value;
param_details[i].sSourceSystem = m_pADORecordSet->Fields->GetItem(short(7))->Value;
param_details[i].sSourceAtt = m_pADORecordSet->Fields->GetItem(short(8))->Value;
const bool isstr = m_pADORecordSet->Fields->GetItem(short(1))->Value.intVal != 0;
const bool isnum = m_pADORecordSet->Fields->GetItem(short(2))->Value.intVal != 0;
const bool isint = m_pADORecordSet->Fields->GetItem(short(3))->Value.intVal != 0;
_variant_t val;
if (isstr)
{
val = m_pADORecordSet->Fields->GetItem(short(4))->Value;
}
else if (isnum)
{
val = m_pADORecordSet->Fields->GetItem(short(5))->Value;
}
else if (isint)
{
val = m_pADORecordSet->Fields->GetItem(short(6))->Value;
}
_variant_t vDTValue = m_pADORecordSet->Fields->GetItem(short(14))->Value;
_variant_t vDT2Value = m_pADORecordSet->Fields->GetItem(short(15))->Value;
VariantValueCopy(¶m_details[i].Default, val, vDTValue, vDT2Value);
if (val.vt == VT_ERROR)
{
// VariantValueCopy checks vDT2Value to see if val.vt can be converted to GDAITEM.
// If it fails here then should check VariantValueCopy, SQL db and the conversion code to GDAITEM.
log(L_ERROR, "%s: pnt=%d prm=%d fail to convert err=%x", __FUNCTION__, pointid, paramid, val.scode);
}
param_details[i].vMinValue = m_pADORecordSet->Fields->GetItem(short(9))->Value;
if (param_details[i].vMinValue.vt != VT_NULL)
{
param_details[i].vMinValue.ChangeType(VT_R4);
}
param_details[i].vMaxValue = m_pADORecordSet->Fields->GetItem(short(10))->Value;
if (param_details[i].vMaxValue.vt != VT_NULL)
{
param_details[i].vMaxValue.ChangeType(VT_R4);
}
param_details[i].sICONFIGAccess = m_pADORecordSet->Fields->GetItem(short(11))->Value;
param_details[i].AttributeName= _bstr_t(m_pADORecordSet->Fields->GetItem(short(12))->Value);
param_details[i].lOrdinal= m_pADORecordSet->Fields->GetItem(short(13))->Value;
dbcache::param.add(param_details[i].AttributeName, 0, paramid);
m_pADORecordSet->Close();
}
else
{
param_details[i].AttributeName = CA2W(dbcache::param.get_name(paramid).c_str());
}
}
catch (_com_error &e)
{
log(L_LOG, "%s: exception caught %S", __FUNCTION__, e.ErrorMessage());
}
}
paramcmd->ActiveConnection = NULL;
paramcmd = NULL;
DWORD took = GetTickCount() - start_time;
log(L_LOG, "%s: exit count=%d took=%dms", __FUNCTION__, PointNames.size(), took);
return S_OK;
}
First of all, use the [code][/code] tags (or the </> button in the toolbar) to embed your code. Edit your post.
Well, I doubt it is the Execute() itself. Do you close all references?
Well, I doubt it is the Execute() itself. Do you close all references?
if (m_pADORecordSet->State == adStateOpen)
m_pADORecordSet->Close();
m_pADORecordSet = paramcmd->Execute(NULL, NULL, NULL);
if (m_pADORecordSet->State == adStateOpen &&
!(m_pADORecordSet->BOF) &&
!(m_pADORecordSet->adoEOF))
{
// ..
m_pADORecordSet->Close();
}
else
{
param_details[i].AttributeName = CA2W(dbcache::param.get_name(paramid).c_str());
}
The problem is that you don't close it in all cases.. the above should imho read:if (m_pADORecordSet->State == adStateOpen)
m_pADORecordSet->Close();
m_pADORecordSet = paramcmd->Execute(NULL, NULL, NULL);
if (m_pADORecordSet->State == adStateOpen)
{
if (!(m_pADORecordSet->BOF) && !(m_pADORecordSet->adoEOF))
{
// ..
}
else
{
param_details[i].AttributeName = CA2W(dbcache::param.get_name(paramid).c_str());
}
m_pADORecordSet->Close();
}
get updates from MSFT- to fix lit. BTW: why do you think you have memory leak?
This question needs an answer!
Become an EE member today
7 DAY FREE TRIALMembers can start a 7-Day Free trial then enjoy unlimited access to the platform.
View membership options
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.
ASKER
ntdll!RtlValidateProcessHeaps+249
ntdll!LdrSetAppCompatDllRedirectionCallback+F52D
ntdll!RtlAllocateHeap+32
combase!PropVariantCopy+566
OLEAUT32!SysFreeString+7F
OLEAUT32!SysAllocStringLen+40
msado15!???+0 : 6AF3DC9C
msado15!???+0 : 6AF3E04E
msado15!???+0 : 6AF38C12
msado15!DllUnregisterServer+ED29
msado15!DllUnregisterServer+32E69
........................................................