The following code causes a memory leak (actually, several, since it is run
numerous times).  The problem is in the function BuildAnswerString, because
when I comment the call to that function and instead simply copy a new value
into the newData string (in SaveCurrentAnswer) the memory leaks are
eliminated.  However, I can't figure out how to fix this.  The problem is
definitely the MemPtrNew allocation in BuildAnswerString, but when I try and
free the pointer with MemPtrFree at the very end of the function, the
database doesn't end up with the right values.  I believe that this is
because the pointers that have been set in EditQuestionRecord (called at the
end of BuildAnswerString) are no longer valid once the memory is freed.  How
do I fix this problem?

****************************************************************************
*********
code
****************************************************************************
*********

/*--------------------------------------------------------------------------
-----------------------------------------------------------
Function: SaveCurrentAnswer
Desccription: saves the answer the user chose on current screen
Parameters: none
Return: none
----------------------------------------------------------------------------
---------------------------------------------------------*/
static void SaveCurrentAnswer(void) {

 UInt32 offset;
 char* newData;

 //create data string
 newData = BuildAnswerString();

 //determine which screen is current
 switch(current_state) {

  case screen1:

   offset=OffsetOf(questions_record_type, Question1Answer);
   break;

  case screen2:

   offset=OffsetOf(questions_record_type, Question2Answer);
   break;

  case screen3:

   offset=OffsetOf(questions_record_type, Question3Answer);
   break;

  case screen4:

   offset=OffsetOf(questions_record_type, Question4Answer);
   break;

  case screen5:

   offset=OffsetOf(questions_record_type, Question5Answer);
   break;

  case screen6:

   offset=OffsetOf(questions_record_type, Question6Answer);
   break;

  case screen7:

   offset=OffsetOf(questions_record_type, Question7Answer);
   break;

  case screen8:

   offset=OffsetOf(questions_record_type, Question8Answer);
   break;

  case screen9:

   offset=OffsetOf(questions_record_type, Question9Answer);
   break;

  case screen10:

   offset=OffsetOf(questions_record_type, Question10Answer);
   break;

  case screen11:

   offset=OffsetOf(questions_record_type, Question11Answer);
   break;

  case screen12:

   offset=OffsetOf(questions_record_type, Question12Answer);
   break;

  case screen13:

   offset=OffsetOf(questions_record_type, Question13Answer);
   break;

  case screen14:

   offset=OffsetOf(questions_record_type, Question14Answer);
   break;

  case screen15:

   offset=OffsetOf(questions_record_type, Question15Details);
   break;

  case screen16:

   offset=OffsetOf(questions_record_type, Question16Details);
   break;

  case thanks:

   //offset=OffsetOf(questions_record_type, Question1Answer);
   break;

 }//switch(current_state)

 //edit record
 EditQuestionRecord(offset,newData,currQuestionIndex);

}//SaveCurrentAnswer

/*--------------------------------------------------------------------------
-----------------------------------------------------------
Function: BuildAnswerString
Desccription: builds string from selected checkboxes
Parameters: none
Return: none
----------------------------------------------------------------------------
---------------------------------------------------------*/
static char* BuildAnswerString(void) {

 UInt16 len=0;
 char* newString;
 Boolean addedSomething=false;

 //get pointers to all checkboxes
 ControlPtr labelP1=GetObjectPtr(AnswerAnswer1Checkbox);
 ControlPtr labelP2=GetObjectPtr(AnswerAnswer2Checkbox);
 ControlPtr labelP3=GetObjectPtr(AnswerAnswer3Checkbox);
 ControlPtr labelP4=GetObjectPtr(AnswerAnswer4Checkbox);
 ControlPtr labelP5=GetObjectPtr(AnswerAnswer5Checkbox);
 ControlPtr labelP6=GetObjectPtr(AnswerAnswer6Checkbox);
 ControlPtr labelP7=GetObjectPtr(AnswerAnswer7Checkbox);

 //read checkbox labels
   char* label1=(char*)CtlGetLabel(labelP1);
 char* label2=(char*)CtlGetLabel(labelP2);
 char* label3=(char*)CtlGetLabel(labelP3);
 char* label4=(char*)CtlGetLabel(labelP4);
 char* label5=(char*)CtlGetLabel(labelP5);
 char* label6=(char*)CtlGetLabel(labelP6);
 char* label7=(char*)CtlGetLabel(labelP7);

 //find out whether boxes are selected
 Boolean label1Selected = (CtlGetValue(labelP1)==1);
 Boolean label2Selected = (CtlGetValue(labelP2)==1);
 Boolean label3Selected = (CtlGetValue(labelP3)==1);
 Boolean label4Selected = (CtlGetValue(labelP4)==1);
 Boolean label5Selected = (CtlGetValue(labelP5)==1);
 Boolean label6Selected = (CtlGetValue(labelP6)==1);
 Boolean label7Selected = (CtlGetValue(labelP7)==1);

 //calculate new string length
 if(label1Selected) {

  len+=StrLen(label1)+2;

 }//if(label1Selected)

 if(label2Selected) {

  len+=StrLen(label2)+2;

 }//if(label2Selected)

 if(label3Selected) {

  len+=StrLen(label3)+2;

 }//if(label3Selected)

 if(label4Selected) {

  len+=StrLen(label4)+2;

 }//if(label4Selected)

 if(label5Selected) {

  len+=StrLen(label5)+2;

 }//if(label5Selected)

 if(label6Selected) {

  len+=StrLen(label6)+2;

 }//if(label6Selected)

 if(label7Selected) {

  len+=StrLen(label7)+2;

 }//if(label7Selected)

 //allocate memory
 newString=MemPtrNew(len);

 if (label1Selected) {

  StrCat(newString, label1);
  addedSomething=true;

 }//if (label1Selected)

 if (label2Selected) {

  if (addedSomething) {

   StrCat(newString, "*");

  }//if (addedSomething)

  StrCat(newString, label2);
  addedSomething=true;

 }//if (label2Selected)

 if (label3Selected) {

  if (addedSomething) {

   StrCat(newString, "*");

  }//if (addedSomething)

  StrCat(newString, label3);
  addedSomething=true;

 }//if (label3Selected)

 if (label4Selected) {

  if (addedSomething) {

   StrCat(newString, "*");

  }//if (addedSomething)

  StrCat(newString, label4);
  addedSomething=true;

 }//if (label4Selected)

 if (label5Selected) {

  if (addedSomething) {

   StrCat(newString, "*");

  }//if (addedSomething)

  StrCat(newString, label5);
  addedSomething=true;

 }//if (label5Selected)

 if (label6Selected) {

  if (addedSomething) {

   StrCat(newString, "*");

  }//if (addedSomething)

  StrCat(newString, label6);
  addedSomething=true;

 }//if (label6Selected)

 if (label7Selected) {

  if (addedSomething) {

   StrCat(newString, "*");

  }//if (addedSomething)

  StrCat(newString, label7);
  addedSomething=true;

 }//if (label7Selected)


 return newString;

}//BuildAnswerString

/*--------------------------------------------------------------------------
-----------------------------------------------------------
Function: EditQuestionRecord
Desccription: edits a record from the questions database
Parameters: offset (UInt32) part of record to edit
Return: none
----------------------------------------------------------------------------
---------------------------------------------------------*/
Err EditQuestionRecord(UInt32 offset, char* newData, UInt16 index) {

 MemHandle h;
    questions_record_type *p;
 Err error=0;

    //grab  a handle to the record
    h = DmGetRecord(questionDatabaseRef, index);

    //if handle was aquired sucesfully
    if (h) {

     //lock handle and grab pointer
        p = (questions_record_type *)MemHandleLock(h);

  error=DmWrite(p, offset,&newData, sizeof(char*));

  //unlock the handle
        MemPtrUnlock(p);

        //release record and set dirty bit
        DmReleaseRecord(questionDatabaseRef,index,true);

    }//if (h)

    //return whether op was successful
    return error;

}//EditQuestionRecord



-- 
For information on using the Palm Developer Forums, or to unsubscribe, please see 
http://www.palmos.com/dev/support/forums/

Reply via email to