Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Frage zu Klasseninitialisierung in D7
Stenkamp - Do 15.07.04 10:21
Titel: Frage zu Klasseninitialisierung in D7
Hallo zusammen,
ich bin da letztens über ein für mich recht unerklärliches Phänomen gestoßen.
Folgender Sourcecode unter D7 umreißt das Problem und sollte meines erachtens nicht laufen...
Das Prog berechnet aber erfolgreich den Wert und funzt tadellos.
Erst beim beenden des Programmes bekommt man einen Fehler.
Kann mir einer erklären:
a: warum funktioniert das ohne sofortigen Laufzeitfehler beim Klassenzugriff?
b: warum erst die verzögerte Fehlermeldung bei Programmende?
Danke,
MtZielscheibe.
PS.: Übrigens, leitet man nicht von TObject, sondern von TComponent ab, bekommt man sofort eine Fehlermeldung.
------------------------------
(Generiert in einem Projekt mit einem Editfeld und einem Button auf der Form)
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29:
| Type TSMS = class (TObject) private FmyVar : Integer; public procedure test; published property myVar: Integer read FmyVar write FmyVar default 0; end;
implementation
procedure TSMS.test; begin myVar:=myVar*10; end;
procedure TForm1.Button1Click(Sender: TObject); Var a:TSMS; begin a.myVar:=10; a.test; edit1.text:=inttostr(a.myVar);
end; |
Moderiert von
Udontknow: Code- durch Delphi-Tags ersetzt.
UC-Chewie - Do 15.07.04 10:26
a zeigt ja auf irgendeine Stelle im Speicher. Das Feld myVar ist um einen zur Compilierzeit bekannten Offset von der Adresse von a entfernt. Die Adresse, auf die a verweist, ergibt sich vor dem Erzeugen des Objekts aus dem Inhalt des Speicherbereichs, den der Objektzeiger innehat. Folglich zeigt a.myVar auf irgendeine Adresse, und wenn in der nichts drinsteht, was vor Schreibzugriff geschützt ist, geht das gut.
Wie auch immer, es ist reine Glückssache, dass das funktioniert. Je nach "Vorgeschichte" deines Programms kann a auf einen geschützten oder nicht geschützten Speicherbereich verweisen.
inselberg - Do 15.07.04 10:30
meiner meinung kommt der laufzeitfehler daher dass
a zerstört werden soll am ende ... und a nie erzeugt wurde
mit a:=TSMS.create; funktioniert doch alles ...
Udontknow - Do 15.07.04 10:31
@Inselberg: Er erzeugt nicht, und er gibt auch nicht frei, trotzdem kriegt er keinen Lauftzeitfehler, und das hatte ihn verwundert.
Cu,
Udontknow
inselberg - Do 15.07.04 10:34
werden nicht alle "erzeugten" (benutzen) objekte zerstört, wenn das übergeordnete (hier form1) objekt zerstört wird?
das ist doch auch der grund warum man nicht expliziet destructoren verwenden muss...
Stenkamp - Do 15.07.04 10:53
Also dass mit dem geschützen Speicher erscheint logisch.
Dennoch verstehe ich dann nicht, warum delphi einen unterschied macht zwischen TObject und TComponent.
wie gesagt, ändert man die klasse von TObject auf TComponent wird sofort beim schreibzugriff auf die property ein Laufzeitfehler ausgelöst.
Und wieso muss ich nicht explizit destructoren verwenden?
Ist damit a.destroy gemeint? Dann ist es klar.
Udontknow - Do 15.07.04 11:15
@Inselberg: nein, das kann man so nicht sagen. TComponent-Nachfahren werden automatisch freigegeben, aber auch nur dann, wenn sie einen Owner zugewiesen haben (der gibt seine untergeordneten Komponenten dann in seinem Destruktor frei). Bei allen anderen Klassen (TStringlist als bekanntes Beispiel) oder TComponent-Nachfahren mit Owner=NIL muss Free bzw. Destroy aufgerufen werden, ansonsten entsteht eine Speicherleiche.
@Stenkamp:
TComponent ist ja ein Nachfahre von TObject. Die Klasse implementiert also Felder und Methoden, die TObject nicht hat. Damit verschiebt sich der von UC-Chewie genannte Offset des Feldes, auf das du zugreifst. Der neu gebildete Offset führt bei der in a angebenen (zufälligen) Adresse zu einer Zugriffsschutzverletzung, der alte Offset eben nicht. Reiner Zufall.
Cu,
Udontknow
inselberg - Do 15.07.04 11:45
| Zitat: |
... werden automatisch freigegeben, aber auch nur dann, wenn sie einen Owner zugewiesen ...
|
Oh Oh das wusst ich nicht .. jetzt weiss ich auch wo mein speicher bleibt *g*
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!