Delphi-PRAXiS
Seite 1 von 4  1 23     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Freigeben -> AV; Bearbeiten -> Nichts weiter (https://www.delphipraxis.net/129669-freigeben-av%3B-bearbeiten-nichts-weiter.html)

xZise 23. Feb 2009 16:55


Freigeben -> AV; Bearbeiten -> Nichts weiter
 
Hallo ihr,

ich habe ein seltsames Problem mit einem Schulprojekt. Und zwar habe ich eine von TObjectList abgeleitete Liste welche Objekte vom Typ TExemplarZeile beinhalten. Diese hat als Vorfahre die Klasse TZeile. Jetzt gibt es noch eine zweite ListenKlasse welche Objekte von Typus TKursZeile aufnimmt. Wenn ich nun die erste mit Daten fülle, kann ich nicht mehr das erste Objekt der zweiten Liste löschen oder freigeben. Weil dann kommt mir einen AV entgegen. Ansonsten kann ich damit arbeiten wie ich will. Wenn ich sogar das Objekt vorher entferne und dann die andere Liste befülle funktioniert alles wunderbar.

Delphi-Quellcode:
Kursliste.LadeAusDatenbank(Datenbank);
// An dieser Stelle funktionieren folgende Aufrufe (natürlich nicht alle gleichzeitig)
Kursliste[0].Free;
// Oder
Kursliste.Delete(0);
Exemplarliste.LadeAusDatenbank(Datenbank);
// Hier aber nicht mehr
Kursliste[0].Free;
// Oder
Kursliste.Delete(0);
Das macht "Exemplarliste.LadeAusDatenbank":
Delphi-Quellcode:
procedure TExemplareZeilenListe.LadeAusDatenbank(const ADatenbank : TDatenbank);
var
  Daten : TExemplarZeile;
  i : Integer;
  ILExemplarIDs, ILPersonenIDs, ILBuchIDs, ILBEIDs : TIntegerList;
  BLAusgedruckt : TBooleanList;
begin
  Clear;
  ILExemplarIDs := TIntegerList.Create;
  ILPersonenIDs := TIntegerList.Create;
  ILBuchIDs := TIntegerList.Create;
  ILBEIDs := TIntegerList.Create;
  BLAusgedruckt := TBooleanList.Create;
  try
    ADatenbank.GibExemplarIDs(ILExemplarIDs);
    ADatenbank.IstAusgedruckt(BLAusgedruckt, ILExemplarIDs);
    ADatenbank.GibBuchIDs(ILBuchIDs, ILExemplarIDs);
    ADatenbank.GibBEIDs(ILBEIDs, ILExemplarIDs);
    ADatenbank.GibPersonen(ILPersonenIDs, ILExemplarIDs);

    for i := 0 to ILExemplarIDs.Count - 1 do
    begin
      Daten := TExemplarZeile.Create;
      Daten.ID := ILExemplarIDs[i];
      Daten.Ausgeliehen := nil;
      Daten.Buch := nil;
      Daten.VPersonenID := ILPersonenIDs[i];
      Daten.VBuchID := ILBuchIDs[i];
      Daten.BEID := ILBEIDs[i];
      Daten.Ausgedruckt := BLAusgedruckt[i];
      Add(Daten);
    end;
  finally
    ILExemplarIDs.Free;
    ILPersonenIDs.Free;
    ILBuchIDs.Free;
    ILBEIDs.Free;
    BLAusgedruckt.Free;
  end;
end;
Ich versuche weiterhin das weiter einzugrenzen, aber im Moment möchte ich euch nicht den ganzen Sourcecode geben. Aber vielleicht hilft euch das schon? Besonders, warum man nicht freigeben kann, aber beispielsweise Werte ändern kann.

MfG
xZise

jaenicke 23. Feb 2009 17:42

Re: Freigeben -> AV; Bearbeiten -> Nichts weiter
 
Was mir spontan dazu einfällt ohne genauer in den Quelltext geschaut zu haben ist die Eigenschaft OwnsObjects. Wenn du die Objekte selbst freigeben willst, etc., dann musst du die auf False setzen. Wenn die TObjectList bei einem Delete oder der Zerstörung der Liste diese selbst aus dem Speicher entfernen soll, dann muss das auf True stehen.

xZise 23. Feb 2009 17:57

Re: Freigeben -> AV; Bearbeiten -> Nichts weiter
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo Sebastian,
OwnObjects ist bei diesen Listen auf true. Aber daran dürfte es nicht liegen, wobei ich da misstrauisch geworden bin :mrgreen: Naja ich habe mich mal daran gesetzt den Code zu entschlacken. Und das Ergebnis hänge ich einfach mal an!

Übrigens ist der Fehler (oder ein anderer?) wo anders. Ich bin der Sache mal auf der Spur.

[edit]Damit ihr wisst wo ihr suchen solltet:
Der Ursprüngliche Fehler tritt in Zeile 39 in UHaupt.pas auf.
Der neue Fehler (oder vielleicht zeigt sich der gleiche einfach anders) in Zeile 207 in UZeilen.pas bzw die Fehlermeldung erscheint, wenn man mit dem Debuger gerade über Zeile 2136 läuft.[/edit]

[edit]Ich bitte alle die es sich bereits heruntergeladen haben, die "db"-Datei zu löschen und durch diese hier im Anhang zu ersetzen.[/edit]

[edit]Folgendes:
In der Schule unter Delphi 2009 --> Fehler beim Zerstören
In der Schule unter Turbo Delphi --> Fehler beim Erstellen aber keinen beim Zerstören des KursEintrages (Z. 39 UHaupt.pas) --> Zerstören der BLAusgedruckt-Liste (Z. 229 UZeilen.pas)[/edit]

MfG
xZise

xZise 24. Feb 2009 12:49

Re: Freigeben -> AV; Bearbeiten -> Nichts weiter
 
Hallo,

wenn ich die alte Variante von meiner UIntegerList/UBooleanList verwende, bekomme ich keine Fehler. Also vermute ich die Probleme dort.

Aber ich weiß nicht, was ich da falsch mache.

MfG
xZise

xZise 25. Feb 2009 21:58

Re: Freigeben -> AV; Bearbeiten -> Nichts weiter
 
Ich möchte ja nicht stören, wüsste aber gerne, was ich da verbrochen habe :)

MfG
xZise

dataspider 26. Feb 2009 07:54

Re: Freigeben -> AV; Bearbeiten -> Nichts weiter
 
Hi,

vielleicht bin ich ja völlig auf dem falschen Dampfer, aber dein Code muss eine Exception werfen, wenn OwnObjects True ist:

Delphi-Quellcode:
Kursliste[0].Free;
// Oder
Kursliste.Delete(0);
Aus TObjectList:

Delphi-Quellcode:
procedure TObjectList.Notify(Ptr: Pointer; Action: TListNotification);
begin
  if OwnsObjects then
    if Action = lnDeleted then
      TObject(Ptr).Free;
  inherited Notify(Ptr, Action);
end;
TObject(Ptr) hast du ja schon freigegeben.

Cu, Frank

jaenicke 26. Feb 2009 11:29

Re: Freigeben -> AV; Bearbeiten -> Nichts weiter
 
Das habe ich oben ja auch schon geschrieben und das passiert ja auch. Wenn die Zeile drin ist, dann gibts den Fehler wie nicht anders zu erwarten beim Zerstören von Kursliste.

Wenn dieser Fehler nicht drin ist, dann tritt der Fehler laut Callstack und Debuggen im CPU-Fenster beim Finalisieren einer Unit auf. Genaueres hab ich jetzt eben noch nicht gesehen.

// EDIT:
Um genau zu sein tritt der Fehler in DoneControls auf, aber:
Es werden auch einige Speicherlecks gemeldet... Um die solltest du dich einmal kümmern, Details sagt dir z.B. FastMM.

xZise 26. Feb 2009 11:46

Re: Freigeben -> AV; Bearbeiten -> Nichts weiter
 
Hallo Sebastian und Frank,

Zitat:

Zitat von jaenicke
// EDIT:
Um genau zu sein tritt der Fehler in DoneControls auf, aber:
Es werden auch einige Speicherlecks gemeldet... Um die solltest du dich einmal kümmern, Details sagt dir z.B. FastMM.

Wann kommen die Speicherlecks? Nachdem der Fehler kommt? Naja wenn man davon ausgeht dass er das Objekt nicht zerstören konnte?

Zitat:

Zitat von jaenicke
Das habe ich oben ja auch schon geschrieben und das passiert ja auch. Wenn die Zeile drin ist, dann gibts den Fehler wie nicht anders zu erwarten beim Zerstören von Kursliste.

Zitat:

Zitat von dataspider
Hi,

vielleicht bin ich ja völlig auf dem falschen Dampfer, aber dein Code muss eine Exception werfen, wenn OwnObjects True ist:

Delphi-Quellcode:
Kursliste[0].Free;
// Oder
Kursliste.Delete(0);

Man beachte das Kommentar. Es ist egal, welchen Befehl ich von beiden ausführe. Bei "Delete(0)" dürfte ja auch kein Fehler kommen.

Und wie gesagt. Es kann zufall sein, dass er nur mit der Integer-/BooleanList im Anhang auftritt.

MfG
xZise

jaenicke 26. Feb 2009 12:01

Re: Freigeben -> AV; Bearbeiten -> Nichts weiter
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von xZise
Wann kommen die Speicherlecks? Nachdem der Fehler kommt? Naja wenn man davon ausgeht dass er das Objekt nicht zerstören konnte?

Alles wird erfolgreich abgearbeitet, erst nach dem eigentlichen FormDestroy tritt eine Zugriffsverletzung bei Adresse 0 auf.

Im Anhang liegt der entsprechende delphiinterne Report.

xZise 26. Feb 2009 16:00

Re: Freigeben -> AV; Bearbeiten -> Nichts weiter
 
Liste der Anhänge anzeigen (Anzahl: 2)
Tach Sebastian,

aber das hat dann nichts mehr mit freigeben zu tun. Weil folgender Code funktioniert:
Delphi-Quellcode:
procedure TFLiberate.FormCreate(Sender: TObject);
begin
  Datenbank := TDatenbank.Create(ExtractFilePath(ParamStr(0)) +  'db');
  ReportMemoryLeaksOnShutdown := true;

  Exemplarliste := TExemplareZeilenListe.Create;
  Kursliste := TKursZeilenListe.Create;

  Kursliste.LadeAusDatenbank(Datenbank);
  Exemplarliste.LadeAusDatenbank(Datenbank);
end;

procedure TFLiberate.FormDestroy(Sender: TObject);
begin
  Exemplarliste.Free;
  Kursliste.Free;

  Datenbank.Free;
end;
Deshalb denke ich, dass irgendwo in der TIntegerList, TBooleanList oder TMainList sein müsste (ich wiederhole mich :) ). Ich hänge einfach die alte Version der TInteger-/TBooleanList an, womit es funktioniert. (Kleiner Hinweis: UMainList dann in der UDatenbank entfernen)

MfG
xZise


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:46 Uhr.
Seite 1 von 4  1 23     Letzte »    

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz