Autor Beitrag
Mortal-Shadow
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 110



BeitragVerfasst: Sa 09.05.09 18:32 
Hi,

Ich bin auf folgendes Problem gestoßen.
Ich brauche für jede Instanz einer Klasse ein Label und erzeuge es deshalb im Creator:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
Constructor TClass.Create(Labeltext : String;
begin
inherited create;
MyLabel := TLabel.Create(nil);
MyLabel.Top := ROW_1_TOP + (ROW_DIFFERENCE * (NumberInList-1));
MyLabel.Left := LABELS_LEFT;
MyLabel.Caption := labeltext;
MyLabel.Parent := FrmEinstellungen.GroupBox;
end;


Jetzt wollte ich es entsprechend im destructor freigeben

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
Destructor TClass.Destroy;
begin
MyLabel.free;
inherited destroy;
end;


Sobald meine Klasse aber zerstört wird bekomme ich ein Accesviolation Error.
Wenn ich entweder dass free im Destructor weglasse, oder aber den mylabel.parent nicht auf die Groupbox
setze, sondern auf nil, bekomme ich den Error nicht.

Mich verwirrt das ganze total.
Erstens dachte ich, dass Parent überhaupt nichts mit freigeben zu tun hat.
Und selbst wenn: Die Groupbox wird zu dem Zeitpunkt ja auch noch nicht freigegeben - er müsste ja nur kommen, wenn ich zuvor die groupbox freigebe.
Zweitens: Wieso sollte sonst ein Error kommen? - Ohne dass .free im destructor würde das label ja noch im Memory rumhängen.


Moderiert von user profile iconNarses: Topic aus Sonstiges (Delphi) verschoben am So 10.05.2009 um 00:12
DeddyH
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Sa 09.05.09 18:51 
Du bist aber sicher, dass sonst nirgends im Code unter gewissen Voraussetzungen das Label freigegeben wird?
Mortal-Shadow Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 110



BeitragVerfasst: Sa 09.05.09 18:56 
Ich habe es gerade erst in den Code eingefügt, und seit dem taucht der Fehler auf -> daraus habe ich geschlossen, dass es am Label liegt.
€: Und beim Debuggen kackt es auch immer beim label.free ab
Und ja, ich bin mir sicher - zumindest wird es nicht direkt freigegeben.
An keiner anderen Steller verwende ich ich das Label.
Aber irgendetwas muss es ja eigentlich freigeben.
Deshalb ja auch meine Verwirrung.

Und wie gesagt, wenn ich keinen Parent angebe funktioniert es ja :?:
(Man sieht es halt nicht.)


Zuletzt bearbeitet von Mortal-Shadow am Sa 09.05.09 19:51, insgesamt 1-mal bearbeitet
DeddyH
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Sa 09.05.09 19:41 
Das verstehe ich im Moment auch nicht. Falls Deine Klasse von TComponent abgeleitet ist, könntest Du diese ja mal testhalber dem Label als Owner mitgeben. Allerdings bezweifle ich, dass sich dadurch etwas ändert.
Yogu
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2598
Erhaltene Danke: 156

Ubuntu 13.04, Win 7
C# (VS 2013)
BeitragVerfasst: Sa 09.05.09 19:55 
Die Zugriffsverletzung ist typisch für den Fehler, einen Owner mit anzugeben, die Komponente dann aber selbst zu zerstören. Wenn der Owner angegeben ist, musst du die Komponente so entfernen:

ausblenden Delphi-Quelltext
1:
2:
Owner.RemoveControl(Panel);
Component.Free;

Wobei Component das Label und Owner dessen Besitzer ist. Das könntest du mal ausprobieren. Allerdings kann ich mir nicht wirklich vorstellen, dass es dem Parent etwas ausmachen sollte, wenn die Komponente freigegeben wird.

Noch eins: Verwende besser FreeAndNil bei Feldern, dann kommt wenigstens an der Stelle garantiert keine Zugriffsverletzung mehr:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
destructor TClass.Destroy;
begin
  FreeAndNil(MyLabel);
  inherited destroy;
end;

Nur zuer Sicherheit: Deine Klasse heißt nicht wirklich TClass, oder? Die gibt es nämlich schon von Haus aus, das könnte zu zusätzlichen Problem führen.
Mortal-Shadow Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 110



BeitragVerfasst: Sa 09.05.09 20:20 
Ich habe geschaut und label.owner ist nil.
Und nein, die Klasse heist nicht TClass, ich habe es so genannt damit voll eindeutig werden soll was das ist. (Auch wenn das T eigentl genügt.)
Aber ich glaube ich habe den Fehler gefunden.
Ich habe ja immer mein Programm beendet, wodurch die Instanzen meiner Klasse freigegeben wurden.
Aber wenn sie an anderen Stellen im Code freigegeben werden, passiert kein Error. (Sprich wenn das Programm noch läuft.)
Beim Debuggen habe ich gemerkt, dass ich alle OnDestroy Aktionen in dem Event einer Form hatte.
Die Form die das Parent des Labels war wurde aber vor den Ondestroy-Aktionen schon freigegeben.
Wenn ich mein OnDestroy hierbei splitte funktioniert alles wieder.