AGB  ·  Datenschutz  ·  Impressum  







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

Problem mit Objektfreigabe

Ein Thema von Suboptimierer · begonnen am 30. Mär 2011 · letzter Beitrag vom 2. Apr 2011
Antwort Antwort
Seite 1 von 2  1 2      
Suboptimierer

Registriert seit: 30. Mär 2011
4 Beiträge
 
#1

Problem mit Objektfreigabe

  Alt 30. Mär 2011, 11:38
Delphi-Version: 2010
Ich habe da wohl ein kleines Problem mit der Freigabe von Objekten, bei dem ihr mir sicher helfen könnt.
Mir ist ein Programm in die Hände gelegt worden, bei dem in einer Klasse in einer Klassenfunktion eine globale Variable iniziiert wird.
Ungefähr so:
Delphi-Quellcode:
TMuster= class(TObject)
  public
//...
end;
//...
var
  Muster: TMuster;

implementation
//...
class procedure TMuster.GetMuster();
begin
  if not assigned(Muster) then
    Muster := TMuster.Create;
//...
Jetzt gibt es haufenweise Stellen, an denen TMuster.GetMuster() aufgerufen wird und ich weiß nicht genau wann der erste, entscheidende Aufruf stattfindet.
Also vorweg: ich weiß, dass globale Variablen nicht so der Hit sind und ich auch schon einen Haufen an globalen Funktionen, Variablen und Konstanten an eine Klasse geklebt habe, aber dieses Objekt bereitet mir noch Kopfschmerzen.

Meine Frage ist, wie ich am elegantesten das Dilemma löse, dass ich beim Beenden des Programms immer Speicherfehler angezeigt bekomme?

Bitte nicht solche Antworten geben wie "Tja, da musst du dein Programm wohl neu schreiben".
Würde es etwas bringen, wenn ich TMuster von TComponent ableite?
Soll ich den Destruktor der Mainform verwenden, um if assigned(Muster) then Muster.free; auszuführen?
Kann ich direkt in TMuster so etwas wie Self.Free im Destruktor verankern?
Wie würdet ihr vorgehen?
  Mit Zitat antworten Zitat
Benutzerbild von rollstuhlfahrer
rollstuhlfahrer

Registriert seit: 1. Aug 2007
Ort: Ludwigshafen am Rhein
1.529 Beiträge
 
Delphi 7 Professional
 
#2

AW: Problem mit Objektfreigabe

  Alt 30. Mär 2011, 11:44
Herzlich willkommen in der DP

Punkt 1: Schau dich mal nach Hier im Forum suchenSingleton um. Da müsste eigentlich eine Beschreibung dabei sein, wie man das wieder aus dem Speicher nimmt.

Meine Frage ist, wie ich am elegantesten das Dilemma löse, dass ich beim Beenden des Programms immer Speicherfehler angezeigt bekomme?
Und was ist die Quelle deines Speicherfehlers? Entfernst du das Objekt oder nicht?

Soll ich den Destruktor der Mainform verwenden, um if assigned(Muster) then Muster.free; auszuführen?
Schon mal ausprobiert?

Und noch was: Eventuell ist die Prüfung einfacher, wenn du Muster mit nil initialisierst. Dann kannst du nämlich auf ungleich nil prüfen und weißt dann, dass ein Objekt existiert.

Bernhard
Bernhard
Iliacos intra muros peccatur et extra!

Geändert von rollstuhlfahrer (30. Mär 2011 um 12:01 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.325 Beiträge
 
Delphi 12 Athens
 
#3

AW: Problem mit Objektfreigabe

  Alt 30. Mär 2011, 12:11
Zitat:
if assigned(Muster) then Muster.free;
if assigned(Muster) then ist eher nutzlos, da .Free dieses intern auch prüft.

Wurde die Variable vorher nicht auf NIL initialisiert, wenn kein Objekt (mehr) drin ist, dann bringt soeine Prüfung auf NIL/Assigned nichts.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.869 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Problem mit Objektfreigabe

  Alt 30. Mär 2011, 12:21
Deshalb ist es wichtig immer FreeAndNil( <Instanz>); statt <Instanz>.Free; zu verwenden
Markus Kinzler
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.351 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Problem mit Objektfreigabe

  Alt 30. Mär 2011, 12:22
Du könntest im Destructor prüfen, ob Deine Objektinstanz Deinem globalen "Muster" entspricht...

Delphi-Quellcode:
destructor TMuster.Destroy;
begin
  if Muster = Self then
    Muster := nil;
  inherited;
end;

Dadurch wird die Verbindung gelöst, egal wann und wie die Instanz aufgelöst wird. FreeAndNil ist dann (in dem Fall) nicht nötig.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.008 Beiträge
 
Delphi 2009 Professional
 
#6

AW: Problem mit Objektfreigabe

  Alt 2. Apr 2011, 10:01
Delphi-Quellcode:
destructor TMuster.Destroy;
begin
  if Muster = Self then
    Muster := nil;
  inherited;
end;
Self nil zuweisen und dann den geerbten Destruktor aufrufen sieht etwas gefährlich aus :o

Michael
Michael Justin
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.351 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Problem mit Objektfreigabe

  Alt 2. Apr 2011, 10:08
Das wäre nur ein gangbarer Weg, wenn Muster nie selbst eine Objektinstanz ist, sondern nur eine globale Variable, die auf ein anderes Objekt zeigt.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Suboptimierer

Registriert seit: 30. Mär 2011
4 Beiträge
 
#8

AW: Problem mit Objektfreigabe

  Alt 30. Mär 2011, 12:28
Meine Frage ist, wie ich am elegantesten das Dilemma löse, dass ich beim Beenden des Programms immer Speicherfehler angezeigt bekomme?
Und was ist die Quelle deines Speicherfehlers? Entfernst du das Objekt oder nicht?
Bisher wird das Objekt wohl noch nicht entfernt. Bevor ich losmachen wollte, wollte ich mich nur nach dem elegantesten Stil umhören.
Die Meldung lautet übrigens so:
Zitat:
---------------------------
Unexpected Memory Leak
---------------------------
An unexpected memory leak has occurred. The unexpected small block leaks are:



1 - 12 bytes: Unknown x 1

13 - 20 bytes: UnicodeString x 8

21 - 28 bytes: UnicodeString x 6

29 - 36 bytes: TCriticalSection x 1, TMuster x 4, UnicodeString x 2


---------------------------
OK
---------------------------
Quelle des Fehlers: ?

Soll ich den Destruktor der Mainform verwenden, um if assigned(Muster) then Muster.free; auszuführen?
Schon mal ausprobiert?
Bisher noch nicht, weil ich vom Gefühl her dies eher für eine schlechtere Variante halte. Meines Erachtens muss sich das Objekt selbst ums aufräumen kümmern, oder der Aufrufer (in diesem Fall nicht feststellbar) oder die ultimative Lösung: der Garbage Collector.

Und noch was: Eventuell ist die Prüfung einfacher, wenn du Muster mit nil initialisierst. Dann kannst du nämlich auf ungleich nil prüfen und weißt dann, dass ein Objekt existiert.
Was meinst du mit einfacher? Weniger Tipparbeit?

Delphi-Quellcode:
destructor TMuster.Destroy;
begin
  if Muster = Self then
    Muster := nil;
  inherited;
end;
Das ist finde ich eine sehr elegante Lösung
Damit brauche ich fremde Objekte nicht belasten. Das werde ich als erstes ausprobieren. Schon einmal danke!
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.351 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: Problem mit Objektfreigabe

  Alt 30. Mär 2011, 12:52
Bisher noch nicht, weil ich vom Gefühl her dies eher für eine schlechtere Variante halte. Meines Erachtens muss sich das Objekt selbst ums aufräumen kümmern, oder der Aufrufer (in diesem Fall nicht feststellbar) oder die ultimative Lösung: der Garbage Collector.
Da kommst Du mit Delphi nicht weit. Das Thema wurde hier kürzlich angerissen.
Objekte (und Referenzen darauf) musst Du selbst auf nil setzen (oder eine Lösung selbst implementieren). Delphi macht das (leider) nicht automatisch.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.325 Beiträge
 
Delphi 12 Athens
 
#10

AW: Problem mit Objektfreigabe

  Alt 30. Mär 2011, 16:15
Meines Erachtens muss sich das Objekt selbst ums aufräumen kümmern, oder der Aufrufer (in diesem Fall nicht feststellbar) oder die ultimative Lösung: der Garbage Collector.
Da kommst Du mit Delphi nicht weit. Das Thema wurde hier kürzlich angerissen.
Objekte (und Referenzen darauf) musst Du selbst auf nil setzen (oder eine Lösung selbst implementieren). Delphi macht das (leider) nicht automatisch.
Wieso soll man das nicht autoatisch hinbekommen?

> Interfaces
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 09:30 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