Thanks for the reply Chris! I still don't seem to find the error. I attached
some of my functions please see if you can spot the error in my code. 
THANKS TO ANY REPLY

-----Original Message-----
From: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED] On Behalf Of Chris Tutty
Sent: 11 August 2005 01:06 AM
To: Palm Developer Forum
Subject: Re: Database: memory reading error

From: "Stephan" <[EMAIL PROTECTED]>
> Hi all!
> I am implementing a database with a list and edit tables similar to the
address example. My problem is after entering text in the second field in my
dataColumn I receive an error (also attached) that my program is reading
from a location in the memory manager's data structures. Any help will be
appreciated!!
>
And an excellent error message it is.  The last sentence about writing
past the end of the buffer says it all.  Check the logic that limits
the amount of data written and the size of the buffers allocated.

Chris Tutty


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

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

/* My table loading function..*/

static void PatientEditFormLoadTable(void)
{
        UInt16          row = 0,numRows;
        UInt16          lineHeight;
        UInt16          fieldIndex, lastFieldIndex;
        UInt16          dataHeight;
        UInt16          tableHeight;
        UInt16          columnWidth;
        UInt16          pos,oldPos;
        UInt16          height, oldHeight;
        FontID          fontID;
        FontID          curFont;
        FormType        *form;
        TableType       *table;
        Boolean         rowUsable;
        Boolean         rowsInserted = false;
        Boolean         lastItemClipped;
        RectangleType   r;
        
        PatientDBRecordType     record;
        MemHandle       recordH;
        PatAppInfoType *appInfo;
        Boolean         fontChanged;
        
        appInfo = MemHandleLock(PatGetAppInfo(gPresPaDB));
        
        form = FrmGetActiveForm();
        
        table = GetObjectPtr(EditPatientEditTable);
        TblGetBounds(table, &r);
        tableHeight = r.extent.y;
        columnWidth = TblGetColumnWidth(table,dataColumn);
        //if a field is currently selected, make sure that it is not above
        // the first visible field.??????????????
        if(gCurrentPatFieldIndex != noFieldIndex)
        {
                if(gCurrentPatFieldIndex < gTopVisiblePatFieldIndex)
                        gTopVisiblePatFieldIndex = gCurrentPatFieldIndex;
        }
        
        
  //  gCurrentPatRecord = TblGetRowID(table, row);
        //Get the current record...
        PatientGetRecord(gPresPaDB, gCurrentPatRecord, &record, &recordH);
        
        row = 0;
        dataHeight = 0;
        oldPos = pos = 0;
        fieldIndex = gTopVisiblePatFieldIndex;
        lastFieldIndex = fieldIndex;
        
        //Load the fields into the table
        while(fieldIndex <= editLastFieldIndex)
        {
                //compute the height of the field's text string.
                height = PatientEditFormGetFieldHeight(table, fieldIndex, 
columnWidth, tableHeight, &record, &fontID);
                
                //Is there enough room for at least one line of data?
                curFont = FntSetFont(fontID);
                lineHeight = FntLineHeight();
                FntSetFont(curFont);
                if(tableHeight >= dataHeight + lineHeight)
                {
                        rowUsable = TblRowUsable(table,row);
                        
                        //Get the height of the current row
                        if(rowUsable)
                                oldHeight = TblGetRowHeight(table, row);
                        else
                                oldHeight = 0;
                                
                        //If the field is not already displayed in the current 
                        // row load the field into the table            
                        if(gROMVersion >= 
sysMakeROMVersion(3,0,0,sysROMStageRelease,0))
                                fontChanged = (TblGetItemFont(table, row, 
dataColumn) != fontID);
                        else
                                fontChanged = false;
                                
                        if((!rowUsable)|| (TblGetRowID(table, row) != 
fieldIndex) || fontChanged)
                        {
                                PatEditInitTableRow(table, row, fieldIndex, 
height, fontID, &record, appInfo);
                        }
                        //If the height or the position of the item has 
changed, draw the item.
                        else if(height != oldHeight)
                        {
                                TblSetRowHeight(table, row, height);
                                TblMarkRowInvalid(table, row);
                        }
                        else if(pos != oldPos)
                        {
                                TblMarkRowInvalid(table, row);
                        }
                        pos += height;
                        oldPos += oldHeight;
                        lastFieldIndex = fieldIndex;
                        fieldIndex++;
                        row++;
                }
                dataHeight += height;
                
                //Is the table full?
                if(dataHeight >= tableHeight)
                {
                        //If a field is currently selected make sure that is 
not below the last 
                        // visible field. If the currently selected field is 
the last visible 
                        // record, make sure the whoel filed is visible

                        if(gCurrentPatFieldIndex == noFieldIndex)
                                break;

                        //above last visible?
                        else if(gCurrentPatFieldIndex < fieldIndex)
                                break;

                        //last visible?
                        else if(fieldIndex == lastFieldIndex)
                        {
                                if((fieldIndex == gTopVisiblePatFieldIndex) || 
(dataHeight == tableHeight))
                                  break;
                        }
                        
                        //remove the top item from the table and reload the 
table again.
                        gTopVisiblePatFieldIndex++;
                        fieldIndex = gTopVisiblePatFieldIndex;
                        
                        row = 0;
                        dataHeight = 0;
                        oldPos = pos = 0;
                }
                        
        }
        
        //Hide the items that don't have any data.
        numRows = TblGetNumberOfRows(table);
        while(row < numRows)
        {
                TblSetRowUsable(table, row, false);
                row++;
        }
        
        //If the table is not full and the first visible field is not the first 
field in
        // the record, display enough fields to fill ou the table by adding 
fields to the 
        // top of the table.
        while(dataHeight < tableHeight)
        {
                fieldIndex = gTopVisiblePatFieldIndex;
                if(fieldIndex == 0)
                        break;
                fieldIndex--;
                
                //compute the height of the field.
                height = PatientEditFormGetFieldHeight(table, fieldIndex, 
columnWidth, tableHeight, &record, &fontID);
                
                //If adding the item to the table will overflow the height, do 
not add the item
                if(dataHeight + height > tableHeight)
                        break;
                //insert a row before the first row.
                TblInsertRow(table,0);
                
                PatEditInitTableRow(table, 0, fieldIndex, height, fontID, 
&record, appInfo);
                
                gTopVisiblePatFieldIndex = fieldIndex;
                rowsInserted = true;
                dataHeight += height;
        }
        
        //If rows were inserted to fill ou the page, invalidate the table; 
        //It all needs to be redrawn...
        if(rowsInserted)
                TblMarkTableInvalid(table);
        
        //If the height of the table is greater than the height of the table, 
then the 
        // bottom of the last row is clipped and the table is scrollable.
        lastItemClipped = (dataHeight > tableHeight);
        
        //Updated scroll arrows
        PatientEditFormUpdateScrollers(form, lastFieldIndex, lastItemClipped);
        
        MemHandleUnlock(recordH);
        MemPtrUnlock(appInfo);
        
}


static void EditPatientFormNewRecord()
{
    PatientDBRecordType  record;
    Int16               i;
    UInt16              attr;
    Err                         error;
        //PatRecordFlags        flags;
 
    // Set up the new record.
    
    for (i = 0; i < PatientFieldCount; i++)
    {
        record.PatientField[i] = NULL;
    }
    

        //flags.allBits = 1;

    error = PatNewRecord(gPresPaDB, &record, &gCurrentPatRecord);
    if (error)
    {
        // DeviceFullAlert is defined in UICommon.h.  The alert resource
        // itself is part of the ROM resources.
        FrmAlert(DeviceFullAlert);
        return;
    }
      
    // Set the record's category to the category being viewed.
    // If the category is All then set the category to Unfiled.
    DmRecordInfo(gPresPaDB, gCurrentPatRecord, &attr, NULL, NULL);   
    attr &= ~dmRecAttrCategoryMask;
    attr |= ((gCurrentCategory == dmAllCategories) ? dmUnfiledCategory : 
             gCurrentCategory) | dmRecAttrDirty;
    DmSetRecordInfo(gPresPaDB, gCurrentPatRecord, &attr, NULL);

    // Set the global variable that determines which field is the top
    // visible field in the Edit view.
    gTopVisiblePatFieldIndex = 0;
    gCurrentPatFieldIndex = editFirstFieldIndex;
    gEditRowIDWhichHadFocus = editFirstFieldIndex;
    gEditFieldPosition = 0;

    FrmGotoForm(EditPatientForm);
}

Err PatChangeRecord(DmOpenRef db, UInt16 *index, PatientDBRecordType *record, 
                    PatRecordFlags changedFields)
{
    PatientDBRecordType  src;
    MemHandle  srcH;
    Err        result;
    MemHandle  recordH = 0;
    MemHandle  oldH;
    Int16      i;
    UInt32     changes = changedFields.allBits;
    PatAppInfoType  *appInfo;
    Boolean    move = true;
    UInt16     attributes;
    PatientPackedDBRecordType*  cmp;
    PatientPackedDBRecordType*  packed;
 
 
    // ChangeRecord does not assume that record is completely valid,
    // so it retrieves a valid pointer to the record.
    if ((result = PatientGetRecord(db, *index, &src, &srcH)) != 0)
        return result;
   
    // Apply the changes to the valid record.
    for (i = 0; i < PatientFieldCount; i++)
    {
        // If the flag is set, point to the string, otherwise point to
        // NULL.
        if (GetBitMacro(changes, i) != 0)
        {
            src.PatientField[i] = record->PatientField[i];
            RemoveBitMacro(changes, i);
        }
        if (changes == 0)
            break;      // no more changes
    }

    // Make a new chunk with the correct size.
    recordH = DmNewHandle(db, PatUnpackedSize(&src));
    if (recordH == NULL)
    {
        MemHandleUnlock(srcH);  // undo lock from GetRecord above
        return dmErrMemError;
    }
    packed = MemHandleLock(recordH);

    // Copy the data from the unpacked record to the packed one.
    PackPatRecord(&src, packed);
 
    // The original record is copied and no longer needed.
    MemHandleUnlock(srcH);
 
    // Check if any of the key fields have changed.  If they have not
    // changed, this record is already in its proper place in the
    // database, and LibChangeRecord can skip re-sorting the record.
    if (changedFields.allBits == 0) 
        move = false;
   
    // Make sure *index-1 < *index < *index+1; if so, the record is
    // already in sorted order.  Deleted records are stored at the end
    // of the database, so ChangeRecord must also make sure not to
    // sort this record past the end of any deleted records. 
    if (move)
    {
        appInfo = MemHandleLock(PatGetAppInfo(db));
        MemPtrUnlock(appInfo);
 
        if (*index > 0)
        {
            // Compare this record to the record before it.
            cmp = MemHandleLock(DmQueryRecord(db, *index - 1));
            move = (PatComparePackedRecords(cmp, packed, NULL, NULL, NULL, NULL 
 ) > 0);
            MemPtrUnlock(cmp);
        }
        else
        {
            move = false;
        }
      
        if (*index + 1 < DmNumRecords(db))
        {
            // Be sure not to move the record beyond the deleted
            // records at the end of the database.
            DmRecordInfo(db, *index + 1, &attributes, NULL, NULL);
            if (! (attributes & dmRecAttrDelete))
            {
                // Compare this record to the record after it.
                cmp = MemHandleLock(DmQueryRecord(db, *index + 1));
                move = (! move) && (PatComparePackedRecords(packed, cmp, NULL, 
NULL, NULL, NULL ) > 0); 
                MemPtrUnlock(cmp);
            }
        }
    }
 
    if (move)
    {
        // The record isn't in the right position, so move it.
        i = PatientFindSortPos(db, packed, NULL, NULL, NULL, NULL);
        DmMoveRecord(db, *index, i);
        if (i > *index)
            i--;
        *index = i;  // Return new record database position.
    }

    // Attach the new record to the old index, which preserves the 
    // category and record ID.
    result = DmAttachRecord(db, index, recordH, &oldH);
    MemPtrUnlock(packed);
    if (result) return result;
 
    MemHandleFree(oldH);
    return 0;
}


Err PatNewRecord(DmOpenRef db, PatientDBRecordType *record, UInt16 *index)
{
        MemHandle       recordH;
        Err                     error;
        PatientPackedDBRecordType *packed;
        UInt16          newIndex;
        
        //Allocate a chuck large enough to hold the new record
        recordH = DmNewHandle(db, PatUnpackedSize(record));
        if(recordH == NULL)
                return dmErrMemError;
                
        //Copy the data from the unpacked record to the packed one.
        packed = MemHandleLock(recordH);
        PackPatRecord(record, packed);
        
        //Get the index of the new record.
        newIndex = DmFindSortPosition(db, &record, NULL, (DmComparF*) 
PatComparePackedRecords, NULL);
        MemPtrUnlock(packed);
        
        //Attach the new record in place and return the new index of the new 
record in the index parameter
        error = DmAttachRecord(db, &newIndex, recordH, 0);
        if(error)
                MemHandleFree(recordH);
        else
                *index = newIndex;
        return error;
}

static void PackPatRecord(PatientDBRecordType *record, MemPtr recordDBEntry)
{
        UInt16  offset;
        Int16   index = 0;
        UInt16  length = 0;
        MemPtr  p;
        PatRecordFlags flags;
        PatientPackedDBRecordType *packed =0;
        
        flags.allBits = 0;
        offset = 0;
        
        for(index = 0; index < PatientFieldCount; index++)
        {
                if(record->PatientField[index] != NULL)
                {
                        p = record->PatientField[index];
                        length += StrLen(p)+1;
                        // Write text field data to  packed record
                        DmWrite(recordDBEntry, offset, p, length);
                        offset += length;
                        SetBitMacro(flags.allBits, index);
                }
        }
        //Write field flags to packed record.
        DmWrite(recordDBEntry, (UInt32)&packed->flags.allBits, &flags.allBits, 
sizeof(flags.allBits));

}

Reply via email to