Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   dynamischer Record führt zu Problemen bei Programm beenden (https://www.delphipraxis.net/208235-dynamischer-record-fuehrt-zu-problemen-bei-programm-beenden.html)

-n1h1l- 1. Jul 2021 05:53

dynamischer Record führt zu Problemen bei Programm beenden
 
Moin, folgendes Problem habe ich an dem ich verzweifel. Ich erstelle ein array von einem eigenem record. Beim beenden free ich alle erstellten komponenten des records. sobald ich eine weitere Komponente in den record aufnehme bekomme ich immer (egal welche art von komponente Button oder Panel) eine Zugriffsverletzung beim beenden. erstellen und sehen klappt ohne Probleme.

ich habe ein Record wie folgt definiert:

type TKalenderTag = record
ids : array[0..3] of string;
Box : TGroupBox;
Tage : array[0..3] of TCheckBox;
BG : array[0..3] of TPanel;
// about : array[0..3] of TPanel;
end;


und Kalender : array of TKalenderTag;


zur Laufzeit erstelle ich in einer Schleife dynamisch Komponenten für Checkbox Groupbox und Panel:

procedure TForm2.createCalender(pMain : TPanel);
var i,j,p : integer;
begin
SetLength(Kalender,34);
q := 0;

for j := 0 to 5 do
begin
for i := 0 to 6 do
begin
Kalender[q].Box := TGroupBox.Create(pMain);
with Kalender[q].Box do
begin
Parent := pMain;
Height := 120;
width := 110;
text := '0'+ inttostr(q);
TextSettings.Font.Size := 16;
TextSettings.Font.Style := [TFontStyle.fsBold];
Position.Y := 147*j + 41;
Position.X := (110*i);
StyleLookup := 'GroupBox4Style1';
end;

for p := 0 to 3 do
begin
Kalender[q].BG[p] := Tpanel.Create(self);
with Kalender[q].BG[p] do
begin
parent := Kalender[q].Box;
Height := 30;
// StyleLookup := 'Panelgreen';
Margins.Left := 3;
Margins.Right := 3;
Align := TAlignLayout.Top;
end;
{
Kalender[q].about[p] := Tpanel.Create(self);
with Kalender[q].about[p] do
begin
parent := Kalender[q].Box;
Height := 30;
Margins.Left := 3;
Margins.Right := 3;
end;
}

Kalender[q].Tage[p] := Tcheckbox.Create(self);
with Kalender[q].Tage[p] do
begin
parent := Kalender[q].BG[p];
Align := TAlignLayout.left;
StyleLookup := 'KalenderCheckstyle';
width:= 50;
case p of
0: Text := 'T-V';
1: Text := 'N-V';
2: Text := 'T-A';
3: Text := 'N-A';
end;

end;
end;



Kalender[q].BG[0].Margins.top := 25;
inc(q);
end;
end;
end;


wenn ich das formular beende, "befreie" ich die die erstellten komponenten wie folgt:

var
I: Integer;
j: Integer;
begin

for I := 0 to 33 do
begin

for j := 0 to 3 do
begin

FreeAndNil(Form2.Kalender[i].Tage[j]);
// FreeAndNil(Form2.Kalender[i].about[j]);
Freeandnil(Form2.Kalender[i].BG[j]);

end;

Freeandnil(Form2.Kalender[i].Box);
end;

wenn ich about als Panel oder Button in den quellcode nehme erhalte ich beim beenden eine ZUgriffsverletzung. Ich verstehe einfach nicht warum das problem entsteht zumal es mit dem rest funktioniert. Warum macht es probleme, wenn ich es nur um eine sache erweiter???

Vielen Dank für eure Hilfe!

Ach die zugriffsverletzung kommt bei i=1 und j=0

Amateurprofi 1. Jul 2021 06:12

AW: dynamischer Record führt zu Problemen bei Programm beenden
 
Ich nehme an, du machst das im FormClose.
Wenn das so ist, dann hilft es vielleicht, das erst im FormDestroy zu machen.

-n1h1l- 1. Jul 2021 06:17

AW: dynamischer Record führt zu Problemen bei Programm beenden
 
danke für den Hinweis! hat leider keine Auswirkung! weiterhin Zugriffsverletzung nur sieht die etwas anders aus:)

DeddyH 1. Jul 2021 06:50

AW: dynamischer Record führt zu Problemen bei Programm beenden
 
Zunächst: schließe Delphi-Code doch bitte in Delphi-Tags ein. Dann noch einige Punkte:
- Vermeide die Verwendung von with, das bringt nur Probleme, speziell beim Debuggen
- Da Du den dynamisch erstellten Komponenten einen Owner zuweist, kümmert der sich schon um die Freigabe, das musst Du gar nicht selbst machen
- In Schleifen über ein Array empfiehlt sich die Verwendung von Low() und High(), das funktioniert dann auch noch, falls sich mal die Länge ändern sollte
- Falls Du das aber unbedingt selbst übernehmen möchtest, könntest Du aus dem Record eine Klasse machen, die sich in ihrem Destruktor um die Freigaben kümmert

sakura 1. Jul 2021 06:59

AW: dynamischer Record führt zu Problemen bei Programm beenden
 
Wenn das Form zerstört wird, werden auch alle darin enthaltenen Controls automatisch zerstört, Du musst diese gar nicht freigeben, das passiert automatisch. Tust Du es doch, kommt es zu einer Zugriffsverletzung ;-)

...:cat:...

-n1h1l- 1. Jul 2021 07:38

AW: dynamischer Record führt zu Problemen bei Programm beenden
 
ich danke euch, ich habe die tipps umgesetzt und jetzt gehts :)

Blup 1. Jul 2021 11:20

AW: dynamischer Record führt zu Problemen bei Programm beenden
 
Konkret:
Die Komponenten werden automatisch freigegeben, weil er beim Create() einen Owner angegeben hat.
Der ist für die Freigabe zuständig.

Das die Komponenten auf dem Formular liegen (Parent) hat nichts mit der Freigabe zu tun.

himitsu 1. Jul 2021 11:27

AW: dynamischer Record führt zu Problemen bei Programm beenden
 
Selbst ohne Owner würde hier freigegeben (also auch bei NIL im Create),

da die VCL (ab TWinControl) zusätzlich auch über die Parent-Beziehungen (alle Childs) freigibt, nicht nur durch die Owner-Beziehungen. (hier hat man leider die WinAPI nachgemacht und deren Verhalten beibehalten)


PS: man kann auch einen eigenen "Owner" verwenden, z.B. ein Dummy-TComponent oder z.B. ein TPanel (woauf das eigene Zeugs liegt) oder TButton (in dem es erstellt wurde) als Owner ans Create übergeben,
worin man dann friedlich die Components freigeben kann. (wurden Komponenten vorher schon freigegeben, dann haben sie sich bereits selbstständig da rausgelöscht)

Es gab auch eine TComponentList, in der sich freigegebenen Komponenten ebenfalls seltstängig daraus entfernen. (also anstatt selbst direkt über den Owner zu gehen)


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:21 Uhr.

Powered by vBulletin® Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf