Autor Beitrag
Stenkamp
Hält's aus hier
Beiträge: 2



BeitragVerfasst: Do 15.07.04 10:21 
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)

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 531

WinXP
D5 Ent
BeitragVerfasst: 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.

_________________
Egal wie dumm man selbst ist, es gibt immer andere, die noch dümmer sind
inselberg
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 458



BeitragVerfasst: 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 ...

_________________
hans bist du das ?
Udontknow
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2596

Win7
D2006 WIN32, .NET (C#)
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 458



BeitragVerfasst: 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...

_________________
hans bist du das ?
Stenkamp Threadstarter
Hält's aus hier
Beiträge: 2



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2596

Win7
D2006 WIN32, .NET (C#)
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 458



BeitragVerfasst: 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*

_________________
hans bist du das ?