Problem mit Komponente freigeben
-
Servus!
Ich habe mir für meinen CBuilder5 eine Delphi Komponente umgeschrieben und bekomme die Meldung "fehler: zugriffsverletzung bei adresse 00000101. lesen bei adresse 00000101" wenn ich die Komponente vom Formular zur Entwicklungszeit wieder löschen möchte.
Wenn ich die beiden Speedbutton auskommentiere gehts..
es geht aber auch wenn ich diese drin lasse und statt dessen das Panel auskommentiere.
destructor TMyEditEx.Destroy; begin if ProgressBar <> nil then ProgressBar.Free; [b]//if FSpeedButton1 <> nil then FSpeedButton1.Free; [/b] [b]//if FSpeedButton2 <> nil then FSpeedButton2.Free; [/b] if FPanel <> nil then FPanel.Free; inherited Destroy; end; [b] // Auch dies funktioniert fehlerfrei[/b] destructor TMyEditEx.Destroy; begin if ProgressBar <> nil then ProgressBar.Free; if FSpeedButton1 <> nil then FSpeedButton1.Free; if FSpeedButton2 <> nil then FSpeedButton2.Free; [b]//if FPanel <> nil then FPanel.Free; [/b] inherited Destroy; end;Erstellt werden beide so
FPanel := TTePanel.Create(Self); with FPanel do begin Parent := Self; BevelOuter := bvNone; end; FSpeedButton1 := TTeSpeedButton.Create(FPanel); with FSpeedButton1 do begin Parent := FPanel; Visible := true; Top := 0; Left := 0; Width := 21; NumGlyphs := 4; Invalidate; OnMouseDown := SpeedButton1MouseDown; OnMouseUp := SpeedButton1MouseUp; end;Da ich beides einzeln freen kann aber nicht zusammen, gibts beim erstellen etwas das ich hätte beachten müssen bzw beim freen?
-
Hm, ich würde mal sagen, da Du bei den Speedbuttons das Panel als Owner angibst, ist das Panel für der 'freeierung' zuständig. Setz testweise mal den Owner der Speedbuttons auf NULL (nil? self?), dann sollte das funktionieren. Respektive im Umkehrschluß brauchst Du die Speedbuttons nicht explizit freizugeben, das der Owner das implizit macht.
-
Hallo,
Du erstellst das Panel mit self als Owner und
die Buttons mit dem Panel als Owner.
D.h. für das Löschen des Panels ist Deine Komponente
zuständig, was wohl automatisch gemacht wird.
Für das Löschen der Buttons ist wiederum das Panel
zuständig.Du musst Dich also nur um das Löschen des Panels selber
kümmern, die Buttons werden dann automatisch vom Panel
gelöscht.Die erste Version sollte meiner Meinung nach korrekt sein.
Gruß
Alexander
-
FSpeedButton1 := TTeSpeedButton.Create(Self); //Parent := FPanel;Bringt leider den selben Fehler.

Es mag so sein das das Panel die SpeedButton ebenfalls löscht, aber man wird diese auf jedenfall auch seperat löschen dürfen, ansonsten könnte man ja keine Komponente mehr entfernen. und müsste immer das komplette Panel in diesem Falle löschen.
Achja was ich vergas, ab und an kann ich die Komponente entfernen ohne diese Fehlermeldung.
-
Junt schrieb:
FSpeedButton1 := TTeSpeedButton.Create(Self); //Parent := FPanel;Bringt leider den selben Fehler.

Jetzt hast Du Deine Komponente als Owner eingetragen.
Möglicherweise musst Du auch gar nichts selbst löschen, da Du
inherited Destroy aufrufst. Ich vermute mal, Deine Komponente
erbt von einer "normalen" Delphi-Komponente, also keine abstrakte
Komponente. Dann sollte diese Komponente automatisch alle Komponenten
löschen, für die sie als Owner eingetragen ist.Junt schrieb:
man wird diese auf jedenfall auch seperat löschen dürfen
Nein. Normalerweise ist der Owner für das Löschen zuständig. Beim BCB kracht
es da regelmäßig, wenn man dem Owner die Komponente, für deren Löschung er
zuständig ist, unter dem Hintern weglöscht.Entweder erstellst Du die Komponenten mit Owner nil oder löschst die Komponente
mit RemoveComponent(). Kann sein, dass Du dann die Komponente über Free() frei-
geben musst.Gruß
Alexander
-
Ist ein TEdit, welches zusätzlich um eine Gauge und zwei SpeedButton auf einem Panel erweitert wurde.
TMyEditEx = class(TEdit) begin ... public: constructor Create(AOwner: TComponent); override; ... end; constructor TMyEditEx.Create(AOwner: TComponent); begin inherited Create(AOwner); ... end;Wen dem so ist wäre ja fein, will kein Speicherleck haben

-
Junta schrieb:
Ist ein TEdit, welches zusätzlich um eine Gauge und zwei SpeedButton auf einem Panel erweitert wurde.
Da ist natürlich die Frage, ob ein TEdit überhaupt ein Parent von einem anderen Steuerelement sein kann.
Syntaktisch vermutlich korrekt, aber sinnvoll? Normalerweise sollte ein Parent ein Container sein, z.B. TPanel, TScrollBox etc.
Ich würde vielleicht ein Panel unter alles legen, d.h. die Komponente von TPanel ableiten.Junta schrieb:
Wen dem so ist wäre ja fein, will kein Speicherleck haben
Wer will das schon?
Folgende Vorschläge:1. Breakpoint im Destruktor setzen und in die Destruktoren des Buttons/Panels reindebuggen.
Falls Du nicht reindebuggen kannst, testweise eine weitere Komponente erstellen, in die
Du dann reindebuggen kannst (nur um festzustellen, ob der Destruktor aufgerufen wird).2. Eine kleine Testapplikation schreiben, die in einer Schleife viele Deiner Komponenten
erstellt und wieder löscht. Dabei den Speicherbedarf kontrollieren.3. Eine BCB-Applikation mit Deiner Komponente erstellen und CodeGuard anschmeißen.
Gruß
Alexander