We help IT Professionals succeed at work.
Get Started
Private
Troubleshooting Question

ADODB Command memory leak on execute()

28 Views
Last Modified: 2020-11-19
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(&param_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;
}
Comment
Watch Question
This question hasn't been answered yet.
While you wait, find out how you can maximize your capability with the most trusted tool in IT.
Explore More Ask a Question
Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant
Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

  • Troubleshooting
  • Research
  • Professional Opinions
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE