Entwickler-Ecke
Sonstiges (Delphi) - Dynamische Felder wieder freigeben !
Jagg - Di 03.12.02 12:06
Titel: Dynamische Felder wieder freigeben !
Hallo,Leute !
Ich habe ein Problem,vllt könnt ihr mir helfen !
Ich habe viele Dynamische Felder erzeugt und Sie müssen wieder freigegeben werden !
Deklaration :
Quelltext
1: 2: 3: 4: 5:
| var L1,L2,L3 : array [1..40] of TLabel; TE : array [1..40] of TEdit; T : TTable; D : TDataSource; i : integer; |
Hauptteil :
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: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66:
| procedure TForm11.FormCreate(Sender: TObject); var i,a,x : integer; begin x := 1; i := 1; a := 0; Image1.Picture.LoadfromFile ('C:\Kasse\ProgrammDaten\Panel1.bmp'); T := TTable.Create(form11); T.DatabaseName := 'C:\BiBA\Mail'; T.TableName := 'Material.dbf'; T.Active := True; while not T.eof do begin if (T['Artnr']>=100)and(T['Artnr']<=139) then begin L1[i] := TLabel.create(Form11); L1[i].parent := Form11; L1[i].Caption :=T['Artnr']; L1[i].Font.Name := 'Lucida Console'; L1[i].Font.Size := 9; L1[i].Font.Style := [fsBold]; L1[i].Top := x*20; L1[i].Left :=55+a; L1[i].Transparent := True;
L2[i] := TLabel.create(Form11); L2[i].parent := Form11; L2[i].Caption :=T['Wasdenn']; L2[i].Font.Name := 'Lucida Console'; L2[i].Font.Size := 9; L2[i].Font.Style := [fsBold]; L2[i].Top := x*20; L2[i].Left := 85+a; L2[i].Transparent := True;
L3[i] := TLabel.create(Form11); L3[i].parent := Form11; L3[i].Caption :=T['Einheit']; L3[i].Font.Name := 'Lucida Console'; L3[i].Font.Size := 9; L3[i].Font.Style := [fsBold]; L3[i].Top := x*20; L3[i].Left := 285+a; L3[i].Transparent := True;
TE[i]:= TEdit.create(Form11); TE[i].parent := Form11; TE[i].Font.Name := 'Lucida Console'; TE[i].Font.Size := 9; TE[i].Font.Style := [fsBold]; TE[i].Top := x*20; TE[i].Left := 335+a; TE[i].Width := 25; TE[i].OnKeyPress := Edit1KeyPress; inc (x); inc (i); if x = 27 then begin a := 350; x := 1; end; end; T.next; end; end; |
Schluß :
Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| T.free; for i := 1 to 40 do begin L1[i].Free; L2[i].Free; L3[i].Free; TE[i].Free; end; |
... ist das mit dem "free" so richtig,ich habe es auch mit der "39" probiert,aber er sagt immer die Fehlermeldung "Zugriffsverletzung auf Adresse" ?
Jagg !
Udontknow - Di 03.12.02 12:12
Hi!
Ich würde mal tippen, dass du eben nicht alle 40 TEdit-Zeiger mit einem Objekt versehen hast, da du wahrscheinlich weniger als 40 Datensätze in der Tabelle hast. Prüfe einfach vorher, ob der Zeiger ungleich NIL ist.
Quelltext
1: 2:
| If MeinObjekt<>NIL then MeinObjekt.Free; |
Cu,
Udontknow
Jagg - Di 03.12.02 12:21
ne,ich habe schon viele datensätze drinne !
aber irgendwas mit dem free ist nicht in ordnung,das weiss ich,kann auch sein,das mit der deklaration was nicht in ordnung ist
die anzahl der arrays oder so !
Ich weiss wirklich nicht mehr weiter...
Jagg !
Udontknow - Di 03.12.02 12:33
*Grummel*
Hast du wirklich 40 Datensätze mit Ids im Bereich 100-139????
Hast du das mit NIL überprüft? Warum prüfst du nicht einfach mal, ob die Zeiger NIL sind, wie ich geschrieben habe! Wenn sie NIL sind, wurden sie:
a) entweder noch nie initialisiert, d.h. es wurde kein Objekt erstellt, oder
b) irgendwo auf NIL gesetzt.
Einfach mal prüfen, das kann doch nicht so schwer sein!
Quelltext
1:
| If L1[i]=NIL then ShowMessage('L'+IntToStr(i)+' ist NIL!'); |
Cu,
Udontknow
Jagg - Di 03.12.02 12:49
Hallo,Also,ich habe das versucht mit dem NIL !
Also,er zeigzt nicht auf nil !
Ich zeig dir mal den code :
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| If L1[i]= NIL then ShowMessage('L'+IntToStr(i)+' ist NIL!'); If L2[i]= NIL then ShowMessage('L'+IntToStr(i)+' ist NIL!'); If L3[i]= NIL then ShowMessage('L'+IntToStr(i)+' ist NIL!'); If TE[i]= NIL then ShowMessage('TE'+IntToStr(i)+' ist NIL!'); {T.free; for i := 1 to 40 do begin L1[i].Free; L2[i].Free; L3[i].Free; TE[i].Free; end;} |
....wie du siehst habe ich das mit dem "free" in geschweiften klmmaern gesetzt und wenn ich das jetzt starte geht alles einwandfrei,aber warum,soviel ich weiss muss man doch free's machen wenn man create gemacht hat ?
LCS - Di 03.12.02 12:54
Hi
auf das Problem mit der richtigen Anzahl hätte ich auch zuerst getippt. Zu prüfen wie Udontknow vorgeschlagen hat solltest du auf jeden Fall. Vielleicht liegts aber auch gar nicht an den Edits sondern an der Tabelle. Hast du mal gecheckt ob die Zugriffsverletzung vielleicht schon an der Stelle entsteht?
Gruss Lothar
Udontknow - Di 03.12.02 13:12
Jagg, Jagg, Jagg!
Weisst du eigentlich, was du da machst? Du prüfst das Array-Element, das hinter dem letzten zugewiesenen Element liegt, da i nach dem "While not eof" genau 1 höher als der letzte zugewiesene Array-Eintrag ist.
Du musst jedes einzelne Array-Mitglied prüfen! Ausserdem solltest du zu Beginn sämtliche Werte mal mit NIL belegen, evtl. steht da einfach irgendwas drin, dann sind die Zeiger nicht NIL.
Initilialisierung:
Quelltext
1: 2: 3: 4: 5: 6: 7:
| for i:=1 to 40 do begin L1[i]:=NIL; L2[i]:=NIL; L3[i]:=NIL; TE[i]:=NIL; end; |
Prüfung bei Freigabe:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| {T.free; for i := 1 to 40 do begin If L1[i]= NIL then ShowMessage('L1['+IntToStr(i)+'] ist NIL!'); If L2[i]= NIL then ShowMessage('L2['+IntToStr(i)+'] ist NIL!'); If L3[i]= NIL then ShowMessage('L3['+IntToStr(i)+'] ist NIL!'); If TE[i]= NIL then ShowMessage('TE['+IntToStr(i)+'] ist NIL!'); L1[i].Free; L2[i].Free; L3[i].Free; TE[i].Free; end;} |
Cu,
Udontknow
Anonymous - Di 03.12.02 13:36
Zum Thema Free und Nil:
Zitat: |
Mit Free wird ein Objekt freigegeben. {...} . Free funktioniert auch dann, wenn das Objekt NIL ist. Es ist also kein Fehler, die Methode für ein Objekt aufzurufen, das niemals initialisiert wurde. |
Man braucht bei Free nicht vorher auf Nil prüfen, da es nicht unbedingst Nil sein muß.
Allerdings könnte man das machen:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| procedure TForm11.Button1Click(Sender: TObject); begin T.Free;
T := nil;
for i := 1 to 40 do begin L1[i].Free; L2[i].Free; L3[i].Free; TE[i].Free;
L1[i] := nil; L2[i] := nil; L3[i] := nil; TE[i] := nil; end; end; |
Versuch es jetzt noch ein mal.
Wenn das ganze aber in TForm11.FormDestroy ist, dann würde ich garnichts freigeben.
Udontknow - Di 03.12.02 13:53
Stimmt. :o
Aber das sollte ja auch nur dazu dienen, festzustellen, ob wirklich alle 40 Objekte erstellt wurden.
Free schlägt mit einer AccessViolation fehl, wenn eben der Zeiger <> NIL ist, sich dahinter aber kein gültiges Objekt verbirgt (z.B. weil der Zeiger eine lokale Variable einer Prozedure ist und nicht mit einem Wert vorbelegt wurde).
Er bekommt eine Zugriffsschutzverletzung, also wird wohl oder übel irgendwas nicht stimmen. Ich tippe auf einen nicht initialisierten Zeiger.
Daher mein Vorschlag mit der Initialisierung und der anschliessenden Prüfung aller 40 Objekte.
Cu,
Udontknow
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!