Autor |
Beitrag |
Jagg
      
Beiträge: 635
|
Verfasst: Di 03.12.02 12:06
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 :
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
      
Beiträge: 2596
Win7
D2006 WIN32, .NET (C#)
|
Verfasst: 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 
      
Beiträge: 635
|
Verfasst: 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
      
Beiträge: 2596
Win7
D2006 WIN32, .NET (C#)
|
Verfasst: 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 
      
Beiträge: 635
|
Verfasst: 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
      
Beiträge: 1305
Erhaltene Danke: 1
WIN 7, WIN 8
Delphi XE5, Delphi XE, Delphi 2007
|
Verfasst: 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
_________________ Der BH ist für die Brust, der Plan ist für'n Ar...
|
|
Udontknow
      
Beiträge: 2596
Win7
D2006 WIN32, .NET (C#)
|
Verfasst: 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
|
|
Popov
Gast
Erhaltene Danke: 1
|
Verfasst: 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
      
Beiträge: 2596
Win7
D2006 WIN32, .NET (C#)
|
Verfasst: Di 03.12.02 13:53
Stimmt.
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
|
|
|