AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Problem beim zerstören von Instanz

Ein Thema von stoermi · begonnen am 4. Jan 2005 · letzter Beitrag vom 10. Jan 2005
Antwort Antwort
stoermi

Registriert seit: 1. Dez 2004
Ort: im Wald von Thüringen
75 Beiträge
 
Delphi 6 Enterprise
 
#1

Problem beim zerstören von Instanz

  Alt 4. Jan 2005, 16:25
Hallo!
Ich hab ein Problem beim zerstören von Instanzen beim Beenden des Programms!
Und zwar habe ich eine Reihe von Instanzen einer Klasse x. In dieser Klasse x befindet sich eine Variable, die auf eine Instanz der Klasse y zeigt.
Am Ende des Programms durchlaufe ich alle Instanzen der Klasse x und schaue mittels assigned, bevor ich sie zerstöre, ob in der Variable noch eine Instanz der Klasse y besteht.
Bringt mir das true, wird auch die Instanz von y zerstört.
Doch jetzt zum Problem: Wenn ich zur Laufzeit bereits durch eine andere Methode die Instanz von y zerstört habe, liefert mir assigned trotzdem true und wenn ich dann die Instanz zerstören will, kommt es zur Exception: der Klasse EConvertError Format '%p' ungültig oder nicht kompatibel mit Argument.
Woran könnte das liegen?

Das wird durchlaufen:
Delphi-Quellcode:
  for i := length(zimmerObj)-1 downto 0 do
  begin
    if assigned(zimmerObj[i].buchung) then
    begin
      if assigned(zimmerObj[i].buchung.kunde) then
      begin
        zimmerObj[i].buchung.kunde.Free;
      end;
      zimmerObj[i].buchung.Free; //Hier nach kommt der Fehler
    end;
    zimmerObj[i].Free;
  end;
Damit zerstöre ich es während der Laufzeit in einem anderen Formular:
Delphi-Quellcode:
    myZimmer.buchung.kunde.Free;
    myZimmer.buchung.Free;
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.117 Beiträge
 
Delphi 11 Alexandria
 
#2

Re: Problem beim zerstören von Instanz

  Alt 4. Jan 2005, 16:29
Moin Stoermi,

da Du in dem Falle wohl nicht FreeAndNil verwenden kannst, sollest Du nach dem .Free noch ein := nil hinzufügen.
Dann klappt auch Assigned.
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
bttb930

Registriert seit: 6. Okt 2003
372 Beiträge
 
#3

Re: Problem beim zerstören von Instanz

  Alt 4. Jan 2005, 17:33
Man muß beim Anwenden von Free gar nicht nachfragen ob die Variable zugewiesen ist oder nicht. Folgendes führt zu keinem Fehler:

Delphi-Quellcode:
  sl := TStringList.Create;
  sl.Free; // gibt die StringList frei. sl ist hinterher NICHT nil, sondern zeigt ins leere
  sl.Free; // funktioniert trotzdem!
Das liegt daran, dass Free eine Klassenfunktion ist. Bei Dir tritt ein Fehler auf, weil Du

  buchung.kunde.Free; aufrufst - das funktioniert nur wenn buchung nicht ins Leere zeigt und nicht nil ist. (Der Fehler ist also nicht das Free, sondern das buchung.kunde - buchung zeigt ins nirvana und kunde ist dort nicht zu finden)

Immer beachten:
Ein Zeiger / eine Klasse die man noch braucht sollte man nach dem Aufruf von Free immer auf nil setzen, damit man an anderer Stelle weiß ob sie auf einen Wert zeigt oder nicht. Das kann man entweder mit zwei Befehlen machen (sl.Free; sl := nil;) oder mit FreeAndNil(sl).

Frage: Warum programmierst Du nicht objektorientiert und gibst den Kunden im Destruktor der Buchung automatisch frei? Dann reiche Buchung.Free; und den ganzen anderen Kram kannst Du dir schenken.
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.117 Beiträge
 
Delphi 11 Alexandria
 
#4

Re: Problem beim zerstören von Instanz

  Alt 4. Jan 2005, 18:24
Moin bttb930,

Zitat von bttb930:
Man muß beim Anwenden von Free gar nicht nachfragen ob die Variable zugewiesen ist oder nicht. Folgendes führt zu keinem Fehler:

Delphi-Quellcode:
  sl := TStringList.Create;
  sl.Free; // gibt die StringList frei. sl ist hinterher NICHT nil, sondern zeigt ins leere
  sl.Free; // funktioniert trotzdem!
Das liegt daran, dass Free eine Klassenfunktion ist.
Free ist keine Klassenfunktion.
Es liegt daran, dass zwischen den Zugriffen der Speicher noch nicht anderweitig verwendet wurde, und somit noch das Objekt enthält.
Das Ganze kann nämlich auch ebensogut auf einen Fehler auflaufen.
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
bttb930

Registriert seit: 6. Okt 2003
372 Beiträge
 
#5

Re: Problem beim zerstören von Instanz

  Alt 10. Jan 2005, 15:15
Stimmt, Free ist tatsächlich keine Klassenfunktion.

Free ist allerdings nicht virtuell, und DAS ist der Grund warum man statt
Delphi-Quellcode:
if self <> nil then
  self.Free;
auch einfach
self.Free; aufrufen kann, denn selbst wenn self = nil ist, findet der Compiler die Funktion Free, da sie nicht virtuell gelinkt wird, sondern statisch. Und Free prüft als erstes ob self = nil ist oder nicht.

Das Beispiel das ich oben geschrieben habe funktioniert (wie Christian schreibt) tatsächlich nur dann, wenn der Speicher noch nicht anderweitig überschrieben wurde, was einfach daran liegt dass nach dem ersten Free sl <> nil ist. Funktioniert also i.d.R. nicht, da davon ausgegangen werden muß, dass der Speicher in der Zwischenzeit überschrieben wurde.

Danke für die Korrektur, Christian, sonst hätte ich meine fehlerhafte Theorie im Kopf behalten.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:27 Uhr.
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