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:=TSMS.create;

  a.myVar:=10//hier sollte es eigentlich einen Laufzeitfehler geben ?!
  a.test;
  edit1.text:=inttostr(a.myVar);

  //a.Free;
end;


Moderiert von user profile iconUdontknow: 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*