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)); }