![]() |
Access Violation im Speichermanager
Liste der Anhänge anzeigen (Anzahl: 3)
Hallo ich habe ein
TDataset das von dem der GExperts abgeleitet ist, es funktioniert mittlerweile auch sehr gut. Das Dataset reicht einfach daten eines X beliebigen TDataset Nachfahren durch. Es dient als Zugriffslayer damit ich nicht ständig den Code ändern muss, wenn ich ne andere Datenbank nutzen. Leider Passiert mir wenn ich in einem verbundenen DBGrid die pfeil Runter taste lange gedrückt halte an einer bestimmten stelle eine AV im Speichermanager. Wenn ich zwischen durch einmal kurz die Pfeiltaste Los lasse und dann dahin scrolle(Locate) passiert nichts. Auch lässt sich der Fehler wenn er einmal aufgetaucht ist nicht nochmal provozieren, es scheint auch alles zu laufen trotz Fehler. Ich habe dazu einige Bilder vom Debugger angehängt. Der Code in dem Es Passiert sieht wie folgt aus:
Delphi-Quellcode:
habt ihr ne idee warum das passiert?
function TVTABLE.AllocateRecordID: Pointer;
Begin if sfRecno in supported then Result := Pointer(FCurRec) else String(Result) := MyDataset.Bookmark;// Hier passiert das. end; |
Re: Access Violation im Speichermanager
Die Funktion AllocateRecordID gibt doch einen Pointer zurück.
Daher ist folgende Zeile:
Delphi-Quellcode:
ziemlich unlogisch.
String(Result) := MyDataset.Bookmark;// Hier passiert das.
Wenn schon, dann doch eher so:
Delphi-Quellcode:
PS: wenn du deine Bilder in GIF umwandelst, brauchen sie wensentlich weniger Speicher und Internetbandbreite. Du kannst deinen Betrag editieren und auch nachträglich neue Versionen (GIF-Datei) hochladen.
function TVTABLE.AllocateRecordID: Pointer;
Begin if sfRecno in supported then Result := Pointer(FCurRec) else Result := PChar(Dataset.Bookmark); // PChar zu Zuweisungkompatibel zu Pointer end; |
Re: Access Violation im Speichermanager
Der Pointer Typ soll eigentlich nur ein Vehikel sein.
Da wird nie als Pointer drauf zugegriffen, Und String ist doch ein 4Byte Typ, oder? Die frage ist auch warum es immer klappt nur einmal irgendwann nicht. Aber ich werde es mal ausprobieren ob das so wie in deinem Code geht. Zur Erklärung: Ich missbrauche den Bookmark als RecNo für Datalinks die mehrere Datensätze Anzeigen wo man einen Gezielt anklicken kann wie dies zum Beispiel im DB Grid der Fall ist. So das alle gebufferten Records einen Bookmark bereithalten. Zu dem ist bei mir RecNo und ein Bookmark schon irgendwie das selbe, und wenn Recno nicht unterstützt wird dann weiche ich komplett auf die angebotenen Bookmarks aus. Wie hier der Fall. Müsste ich dann nicht in den Funktionen auch ne menge verändern? (Die Kommentare im Source sind einfach nur für mich)
Delphi-Quellcode:
function TVTABLE.AllocateRecordID: Pointer;
Begin if sfRecno in supported then Result := Pointer(FCurRec) else String(Result) := MyDataset.Bookmark; end; procedure TVTABLE.DisposeRecordID(Value: Pointer); Begin if not (sfRecno in supported) then If Value <> nil then String(Value) := ''; // Freigabe des Bookmarks sehr sehr wichtig !!! end; procedure TVTABLE.GotoRecordID(Value: Pointer); var old:Integer; Begin if sfRecno in supported then Begin old := FCurRec; FCurRec := Integer(Value); if FCurRec > -1 then Begin SetDataSetRecNo(FCurRec+1)(*evtl. moveby verwenden*) end; end else begin If (Value <> nil) then MyDataset.Bookmark := String(Value); // MyDataset.Bookmark := String(PRecordInfo(Activebuffer + GetDataSize).RecordID^); // A.R. kann man das einfach so auskommentieren? // RecordToBuffer(Activebuffer); // Resync passiert in TDataset.GotoBookmark end end; function TVTABLE.GetBookMarkSize: Integer; Begin if sfrecno in supported then Result := SizeOf(Integer) else Begin Result := SizeOf(String); end; end; procedure TVTABLE.DoGotoBookmark(Bookmark: Pointer); Begin if sfrecno in supported then GotoRecordID(Pointer(PInteger(Bookmark)^)) else GotoRecordID(Bookmark); end; procedure TVTABLE.AllocateBookMark(RecordID: Pointer; Bookmark: Pointer); Begin if sfrecno in supported then PInteger(Bookmark)^ := Integer(RecordID) else Bookmark := RecordID;//Gefahr: Kann sein das das Bookmark bei Navigation zerstört wird. end; |
Re: Access Violation im Speichermanager
Habe mal was ausprobiert:
Hier passiert der Fehler nicht mehr
Delphi-Quellcode:
function TVTABLE.AllocateRecordID: Pointer;
var s:String; Begin if sfRecno in supported then Result := Pointer(FCurRec) else begin try s := MyDataset.Bookmark; String(Result) := s; except Showmessage('Fehler2'+s); end; end; end; Hier passiert der Fehler trotzdem. Scheint so als habe der Speichermanager ein Problem mit dem Managen der Instanzen von Strings. Denn das Freigeben eines Strings während der Zuweisung ist doch irgendwie seltsam.
Delphi-Quellcode:
function TVTABLE.AllocateRecordID: Pointer;
var s:String; Begin if sfRecno in supported then Result := Pointer(FCurRec) else begin try s := MyDataset.Bookmark; String(Result) := s; except Showmessage('Fehler2');// ohne s end; end; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:04 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz