Warum ensteht hier kein Memory Leak ?
-
- Beiträge: 94
- Registriert: So 5. Nov 2006, 18:40
- OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
- CPU-Target: xxBit
- Wohnort: Berlin
Warum ensteht hier kein Memory Leak ?
Hallo,
ich habe in der letzten Zeit öfters so etwas hier gemacht :
ComboBox1.Items:=MyStringList1;
Bis mir dann eingefallen ist, das dann ja Memory Leaks entstehen, schließlich gibt es ja keinen Zeiger mehr auf die alte StringList von Combobox1.
Ich habe zum Test mal mit HeapTrc compiliert und siehe da es hagelte Fehler (wie unerwartet).
Daraufhin das ganze geändert :
ComboBox1.Items.Free;
ComboBox1.Items:=MyStringList1;
So weit alles in Ordnung.
An anderer Stelle mache ich dies hier:
Memo1.Lines:=MyStringList1;
Und egal wie oft ich dieses Konstrukt aufrufe, Heaptrc meldet keinen Fehler
Warum gibt es so kein Memory Leak ? Es gibt doch auch keinen Zeiger mehr auf die alte StringList des Memofeldes.
thx
ich habe in der letzten Zeit öfters so etwas hier gemacht :
ComboBox1.Items:=MyStringList1;
Bis mir dann eingefallen ist, das dann ja Memory Leaks entstehen, schließlich gibt es ja keinen Zeiger mehr auf die alte StringList von Combobox1.
Ich habe zum Test mal mit HeapTrc compiliert und siehe da es hagelte Fehler (wie unerwartet).
Daraufhin das ganze geändert :
ComboBox1.Items.Free;
ComboBox1.Items:=MyStringList1;
So weit alles in Ordnung.
An anderer Stelle mache ich dies hier:
Memo1.Lines:=MyStringList1;
Und egal wie oft ich dieses Konstrukt aufrufe, Heaptrc meldet keinen Fehler
Warum gibt es so kein Memory Leak ? Es gibt doch auch keinen Zeiger mehr auf die alte StringList des Memofeldes.
thx
Re: Warum ensteht hier kein Memory Leak ?
Wieso machst Du's denn überhaupt so?
Mit
ComboBox1.Items.assign(MyStringList1);
ist doch alles in Butter.
Mit
ComboBox1.Items.assign(MyStringList1);
ist doch alles in Butter.
Christian hat geschrieben:Warscheinlich freet tmemo die strings automatisch bei neuzuweisung
Moment mal.
Eigentlich geht das ja gar nicht unter mode objfpc.
ComboBox1.Items:=MyStringList1;
Das gemeinte (bzw in Delphi) wäre doch ComboBox1.Items:=@MyStringList1;
stimmts?
Und tatsächlich wird bei dem Statement ComboBox1.Items:=MyStringList1;
unter GTK die Funktion
procedure TGtkListStringList.Assign(Source : TPersistent);
aufgerufen!
Das ist also nicht wie bei Delphi!!!
Oder liege ich falsch?
danny61 hat geschrieben:Womit ich wieder bei der Frage wäre : Warum treten bei
Memo1.Lines:=MyStringList;
keine Memory Leaks auf ?
Keine Ahnung. Hast Du denn MyStringList auch beide male freigegeben?
Um die Verwirrung von vorhin noch zu klären:
Code: Alles auswählen
procedure TForm1.Button1Click(Sender: TObject);
var SL1,SL2:TStrings;
begin
SL1:=TStringList.create;
Memo1.lines:=SL1; //Property von TMemo, wird implizit Assigned
SL1.Free;
Memo1.Lines.add('Klappt');
SL1:=TStringList.create;
SL2:=TStringList.create;
SL2:=SL1; //Scheint nur den Pointer zu setzen
SL1.free;
SL2.add('Zugriffsverletzung');
end;
-
- Beiträge: 6079
- Registriert: Do 21. Sep 2006, 07:51
- OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
- CPU-Target: AVR,ARM,x86(-64)
- Wohnort: Dessau
- Kontaktdaten:
Memo1.lines:=SL1;
ist in diesem Fall das selbe wie Memo1.Lines.Assign(SL1);
deshalb kann er dei SL1 danach freigeben und zum memo eine zeile hinzufügen
in deinem beispiel heisst das deine memoryleaks treten auf weil du die Stringlist nicht freigibst hinterher
ist in diesem Fall das selbe wie Memo1.Lines.Assign(SL1);
deshalb kann er dei SL1 danach freigeben und zum memo eine zeile hinzufügen
in deinem beispiel heisst das deine memoryleaks treten auf weil du die Stringlist nicht freigibst hinterher
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/
Christian hat geschrieben:Memo1.lines:=SL1;
ist in diesem Fall das selbe wie Memo1.Lines.Assign(SL1);
Genau! Das soll der obige Code zeigen.
Im Fall von TMemo (und anderen) ist Lines ein property.
Die Zuweisung von TStrings an Lines wird über die Procedur SetLines abgewickelt:
procedure TCustomMemo.SetLines(const Value : TStrings);
begin
if (Value <> nil) then
FLines.Assign(Value);
end;
Also es wird eine Kopie des Inhalts gemacht. Beide TStrings sind immer noch da.
Im Fall von SL1:=SL2 wird aber nur der Pointer gleichgesetzt.
D.h. Der Zugriff auf SL1 geht flöten und SL1 zeigt auf das gleiche wie SL2.
Also aufgepasst!
Was ich allerdings immer noch nicht kapiere:
Warum kompiliert SL1:=SL2 im mode objfpc überhaupt?
Ich dachte immer das wäre zwinged SL1:=@SL2
Aber SL1:=@SL2 kompiliert gar nicht:
Error: Incompatible types: got "Pointer" expected "TStrings"
Das hingegen ist Delphi wieder egal.
??? Ich steh auf dem Schlauch....
Warum kompiliert SL1:=SL2 im mode objfpc überhaupt?
Ich dachte immer das wäre zwinged SL1:=@SL2
Aber SL1:=@SL2 kompiliert gar nicht:
Error: Incompatible types: got "Pointer" expected "TStrings"
Das hingegen ist Delphi wieder egal.
??? Ich steh auf dem Schlauch....