Autor Beitrag
Loki
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 34

Win XP Home

BeitragVerfasst: So 31.10.04 19:03 
Hi

Ich bin neu hier und fange gleich mit einer Frage an *ggg*
(hoffe das es mein Problem nicht schon mal gab. Ich hab gesucht aber ich wusste nicht so wirklich wonach ich suchen sollte. Das gleiche Problem hatte ich mit dem Namen des Threads hoffe der ist so verständlich)

Da ist eine Sache die mich heute schon mehrere Stunden beschäftigt also:

Ich habe 2 Objektvariablen in einer Prozedur. Die eine ist vom Typ des Vorfahr der anderen.

Var1 : TVorfahr;
Var2 : TNachfahr;

Zu erst wird die zweite Variable erstellt mit Create.

Var2 := TNachfahr.Create;

Dann wird die erste Variable mit der zweiten belegt.

Var1 := Var2;

So jetzt wird der Speicher von Variable eins wieder freigegeben.

Var2.Free;

Dann hab ich versucht auf Var1 zuzugreifen und in machen Fällen hat es geklappt in anderen nicht.

Das versteh ich dann nicht. Oder ist das ganze nur Zufall gewesen weil der Speicher auf den Var1
zeigt noch nicht wiederverwertet wurde??? Hatte nämlich 3 verschiedene Reaktionen auf den Zugriffsversuch entweder es funktionierte ordnungsgemäß oder ich bekam irgedeinen Kauderwelsch oder es kam ein Zugriffsverletzungsfehler. Deshalb will ich wissen wie das mit dem Speicher in einer Prozedur ist wenn ich free auf eine Variable anwende die ich in der Prozedur deklariere. Wird der dann erst am Ende freigegeben oder dann wenn ich free mache ???
Wenn ich Var1 dann jetzt ganz leer haben möchte würde also dann reichen wenn ich Var1 := nil mache, sodass dann auch kein Speicher mehr unnötig besetzt ist. So hoffe ich hab es verständlich beschrieben :wink: Wenn nicht versuch ich es gerne nochmal also fragt.

Bin da irgendwie mit meinem Latein am Ende :wink:
Ich hoffe das mir jemand helfen kann

MFG

Loki

P.S.: Anbei nochmal der Code oben zusammenhängend mit Code - Tag:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
procedure TTest.Egal;
var  Var1 : TVorfahr;
     Var2 : TNachfahr;
     Test : string;
begin
  Var2 := TNachfahr.Create;
  Var1 := Var2;
  Var2.Free;
  Test := Var1.GetIrgendWas;  //hier kommt dann der Fehler oder es ist wie oben beschrieben  
end;


Moderiert von user profile iconMotzi: Code- durch Delphi-Tags ersetzt.
Keldorn
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 2266
Erhaltene Danke: 4

Vista
D6 Prof, D 2005 Pro, D2007 Pro, DelphiXE2 Pro
BeitragVerfasst: So 31.10.04 19:32 
Zitat:

Var1 := Var2;

So jetzt wird der Speicher von Variable eins wieder freigegeben.

Var2.Free;

Dann hab ich versucht auf Var1 zuzugreifen und in machen Fällen hat es geklappt in anderen nicht.

es existiert nur ein erstelltes objekt, egal ob var1 und var2 erstellst, nach Var1 := Var2; zeigt Var1 auch auf Var2. Damit kannst du das vorher erstellte Var1 nicht mehr freigeben (speicherleck). Var2.free -> damit gibst du das erstellte objekt wieder frei. Jeglicher zugriff darauf endet in einer AV. um das object wirklich zu kopieren, verwende die assign-methode, wenn vorhanden oder durch einzelnes zuweisen der Eigenschaften
ausblenden Delphi-Quelltext
1:
2:
3:
Var1.eigenschaft1 := Var2.eigenschaft1; 
Var1.eigenschaft2 := Var2.eigenschaft2; 
...


hier wird das ganze nochmal erklärt:
www.delphi-source.de...agen/sprache/oo2.php

Mfg Frank

_________________
Lükes Grundlage der Programmierung: Es wird nicht funktionieren.
(Murphy)
Lossy eX
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1048
Erhaltene Danke: 4



BeitragVerfasst: So 31.10.04 19:40 
Als erstes und wichtigest einmal folgendes. Klassenvariablen sind in Wirklichkeit nur POINTER. Wenn du Var1 := Var2 machst, dann hast du immer noch nur eine Klasse. Aber du hast an dieser Stelle zwei Variablen die auf deine Klasseninstanz zeigen. Wenn du bei der einen Free aufrufst, dann gibt Delphi en Speicher frei. Der hat aber immernoch seinen ursprünglichen Inhalt!!! Wenn du direkt danach auf Variablen zugreifst dürfte das sogar noch klappen. Wenn du dann aber eine neue Klasse erstellst kann der Speicher (vollständig oder auch nur teilweise) überschrieben werden. Wenn dies Passiert dann kannst du als ergebniss deines Zugriffen so ziemlich alles bekommen. Angefangen von komischen Werten bis hin zu einer Access Violation.

Um sicherzu stellen, dass niemand mehr auf diese Klasse zugreifst müsstest du alle Variablen auf nil setzen. Dann kannst du mit Gewissheit sagen, dass niemand mehr auf den "falschen" Speicher zugreift.

PS: Wenn du ein und die selbe Klasse mehrmals verwenden willst, dann kannst du auch eine Referenzzählung einbauen. Ähnlich wie dies bei Interfaces der Fall ist. Aber dann hättest du ein globales Objekt welches bei Anforderung der Klasse den Zähler erhöht und bei "ich will nicht mehr" (2 Methoden der Klasse) den Zähler verringert. Bei 0 dann wieder frei gibt und bei Bedarf dann wieder erstellt. Das setze ich ganz gerne ein. Aber das nur mal so am Rande.

_________________
Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
Loki Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 34

Win XP Home

BeitragVerfasst: So 31.10.04 19:44 
Danke für die Klärung des Problems :D
D.h. also das wenn ich am Ende Var1 := nil mache dann ist kein Speicherplatz unnötig belegt oder ?

War jetzt nur verwirrt das ein paar mal das was vorher in Var2 drin stand in Var1 noch drin stand obwohl ich Var2 schon mit free aus dem Speicher entfernt hatte. Also muss es nur Zufall gewesen sein, weil der Speicher noch nicht anders benutzt worden ist oder ?

/EDIT: OK ist jetzt geklärt :D nochmals danke
Lossy eX
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1048
Erhaltene Danke: 4



BeitragVerfasst: Mo 01.11.04 00:45 
Nur noch mal zum Verständniss. Durch Var1:=nil gibst du keinen speicher frei. Du entfernst lediglich die Adresse deiner Klasseninstanze aus einer existierende Variable.

_________________
Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
Loki Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 34

Win XP Home

BeitragVerfasst: Mo 01.11.04 01:34 
Jo klar war etwas unglücklich von mir formuliert :D
Aber danke für den Hinweis