Title: Re: Invalid Address specified to RtlFreeHeap( 00870000, 008A1E90 ) on using FreeInternalIdList
**
 
Angus,

I simplified it for you using rtl...this does all the memory management and error handling for you, and is almost exactly the equivalent code.
 
One other note: Your program would be faster if you are able to use GetListEntryWithField and ask for the two field values right there, instead of one API call per entry.  This will work unless you need to access long character or diary fields.
 
The updated code:
 
#include "server.h"
#include <iostream>
 
long find2Fields(const std::string &formName, const std::string &szSearchQual, std::string &szField1, std::string &szField2,
  long fieldID1, long fieldID2)
{
 try {
  rtl::Server server("hardy-remedy", "Demo", ""); // replace with however you set up your server connection (a global, passed in, whatever)
  rtl::Qualifier qualifier;
  rtl::EntryListFieldValueList entries;
  rtl::IdList idList;
  rtl::FieldValueMap fieldValues;
  server.parseQualification(qualifier, szSearchQual, formName, "");
  unsigned int matches = 0;
  server.getListEntryWithFields(entries, formName, qualifier, idList, rtl::SortList(), 0, 0, &matches);
  if (matches > 0 && entries.size() > 0)
  {
   rtl::EntryListFieldValueList::iterator iter = entries.begin();
   rtl::IdList fieldIdList;
   fieldIdList.push_back(fieldID1);
   fieldIdList.push_back(fieldID2);
   for (; iter != entries.end(); iter++)
   {
    rtl::EntryListFieldValue &entry = *iter;
    // get the entry with the two fields
    server.getEntry(fieldValues, formName, entry.getEntryIdList(), fieldIdList);
    szField1 = fieldValues.get(fieldID1).toString();
    szField2 = fieldValues.get(fieldID2).toString();
   }
  }
  else
  {
   cout << "no matches\n";
  }
  return (matches >= 1) ? 0 : -1;
 } catch (rtl::Exception &err) {
  std::cerr << err.toString().c_str();
  return -1;
 }
}
Dan


From: Angus Comber [mailto:[EMAIL PROTECTED]
Sent: Tue 7/18/2006 1:45 AM
To: [email protected]
Cc: Dan Hardy
Subject: Re: Invalid Address specified to RtlFreeHeap( 00870000, 008A1E90 ) on using FreeInternalIdList

Thanks for your help.

I am using Visual C++ version 6.  Not interested in getting into the MS .NET
nonsense.

Ah just changed to link to the release mode multi-threaded DLL - and now
don't get problem.  What is going on here to cause the crash?

Anyway, for what it's worth here is the function below




function here:
// Eg szFormName = [in] MyNewForm
// Eg szSearchQual = [in] 'MyNewField' = "07768385144" OR 'Field2' =
"07768385144" OR 'Field3' = "07768385144"
// Eg szFieldID1 - [out] string from field1
// Eg szFieldID2 - [out] string from field2
// Eg fieldID1 - [in] fieldid to get data
// Eg fieldID2 - [in] fieldid to get data
long CRemedy::Find2Fields(char* szFormName, char* szSearchQual, char*
szFieldID1, char* szFieldID2,
long fieldID1, long fieldID2)
{
ARQualifierStruct qualstruct;
AREntryListList entry;
unsigned int matches = 0;
ARInternalIdList idlist;
ARFieldValueList fldval;
// Loads specified qualification string
int ret = ARLoadARQualifierStruct(&m_ARctrlstruct, szFormName, NULL,
szSearchQual,
&qualstruct, &m_StatusList);
if(ret == 0)
{
// retrieves list of forms on server - we specify form we are interested in
here
ret = ARGetListEntry(&m_ARctrlstruct, szFormName, &qualstruct, NULL, NULL,
NULL,
AR_NO_MAX_LIST_RETRIEVE, &entry, &matches, &m_StatusList);
if(ret == 0)
{
// printf("matches: %d\n", matches);
if(matches > 0)
{
for(int i=0; i < (int)matches; i++)
{
// printf("Entry: %s\n", entry.entryList[i].entryId.entryIdList[0]);
idlist.numItems = 2; // need two fields
idlist.internalIdList =
(ARInternalId*)malloc(sizeof(ARInternalId) * idlist.numItems);
idlist.internalIdList[0] = fieldID1;
idlist.internalIdList[1] = fieldID2;
ret=ARGetEntry(&m_ARctrlstruct, szFormName, &entry.entryList[i].entryId,
&idlist, &fldval, &m_StatusList);
// can specify NULL for idlist to retrieve ALL fields
if (ret == 0)
{
// fldval.fieldValueList->value.u.charVal is field1 data
// fldval.fieldValueList[1].fieldId is fieldid of that field
strncpy(szFieldID1, fldval.fieldValueList[0].value.u.charVal, 100);
strncpy(szFieldID2, fldval.fieldValueList[1].value.u.charVal, 100);
}
else
{
if (m_StatusList.numItems > 0)
strcpy(m_strLastErrorMsg, m_StatusList.statusList->messageText);
}
}
}
// else
// {
// printf("no matches\n");
// }
}
// else
// {
// printf("getlistentry failed\n");
// }
}
// else
// {
// printf("load qual failed\n");
// }
// FALSE if declared as stack level variable, TRUE for alloc'd mem for
struct
FreeARQualifierStruct(&qualstruct, FALSE);
FreeAREntryListList(&entry, FALSE);
FreeARInternalIdList(&idlist, FALSE);
FreeARFieldValueList(&fldval, FALSE);
FreeARStatusList(&m_StatusList, FALSE);
// freeStruct - A flag indicating whether you need to free the top-level
structure. If you
// allocated memory for the top-level structure, specify 1 (TRUE) to free
both
// the structure and its contents. If you used a stack variable for the
top-level
// structure, specify 0 (FALSE) to free only the contents of the structure.
if (matches < 1)
return -1;
return 0;
}


----- Original Message -----
From: "Dan Hardy" <[EMAIL PROTECTED]>
Newsgroups: public.remedy.arsystem.general
To: <[email protected]>
Sent: Tuesday, July 18, 2006 6:59 AM
Subject: Re: Invalid Address specified to RtlFreeHeap( 00870000, 008A1E90 )
on using FreeInternalIdList



Sure, post the whole function or send it to me privately if you like.  I'll
take a look.

What compiler are you using (VS 6, .NET 2003, etc.), which C Run-time are
you linking with (e.g. static vs dll, release vs debug), and which version
of the Remedy API are you linking with?

It's probably best to link to the release mode multi-threaded DLL and use
Visual Studio 6 if possible, as that's probably what the AR API libraries
were built with.  (I've also used Visual Studio .NET 2003, and while it has
a different run-time, it seems to be okay using the release mode
multi-threaded DLL option).

Dan


__20060125_______________________This posting was submitted with HTML in it___

Reply via email to