使用TList时出现内存泄漏问题.我试图填充填充列表中的Tlist循环并使用数据.下面的代码只是填充列表而不使用它的代码.
private
{ Private Form Variable declarations }
GlblCancel : Boolean;
MyPrintLst : TList;
PrintRecord = record
PrintString1,
PrintString2,
PrintString3,
PrintString4,
PrintString5,
PrintString6 : string;
PrintFloat1,
PrintFloat2,
PrintFloat3 : Double;
end;
PrintPointer = ^PrintRecord;
Procedure TMyForm.Create;
begin
MyPrintLst := TList.Create;
end
Procedure TMyForm.FreeTList(Var List : Tlist; Size : Integer);
Var I, Count : Integer;
begin
Count := list.Count - 1;
For I := Count DownTo 0 Do
FreeMem(List[I], Size);
List.Clear;
List.Free;
end;
Procedure TMyForm.FormClose;
begin
FreeTList(MyPrintLst,SizeOf(PrintRecord));
end
procedure AddToPrintList(PrintList : TList;
Const MyStrings : Array of String;
Const MyDoubles : Array of Double);
var
PrintPtr : PrintPointer;
begin
New(PrintPtr);
IF High(MyStrings) >= 0 Then
PrintPtr^.printString1 := MyStrings[0];
Begin
IF High(MyStrings) >= 1 Then
Begin
PrintPtr^.printString2 := MyStrings[1];
IF High(MyStrings) >= 2 Then
Begin
PrintPtr^.printString3 := MyStrings[2];
IF High(MyStrings) >= 3 Then
Begin
PrintPtr^.printString4 := MyStrings[3];
IF High(MyStrings) >= 4 Then
PrintPtr^.printString5 := MyStrings[4];
Begin
IF High(MyStrings) >= 5 Then
PrintPtr^.printString6 := MyStrings[5];
End; {>=5}
End; {>=4}
End; {>=3}
End; {>=2}
End; {>=1}
IF High(MyDoubles) >= 0 Then
Begin
PrintPtr^.PrintFloat1 := MyDoubles[0];
IF High(MyDoubles) >= 1 Then
Begin
PrintPtr^.PrintFloat2 := MyDoubles[1];
IF High(MyDoubles) >= 2 Then
PrintPtr^.PrintFloat3 := MyDoubles[2];
End;
End;
PrintList.add(PrintPtr);
end;
Procedure TMyForm.Button1.Click;
Var EstReading : LongInt;
begin
EstReading := 0;
ClearTList(MyPrintLst,Sizeof(PrintRecord));
MyQuery.First;
While Not(MyQuery.EOF) Do
begin
EstReading := EstReading + 1;
AddToPrintList(MyPrintLst, [MyQuery.FieldByName('Field1').AsString,
MyQuery.FieldByName('Field2').AsString,
MyQuery.FieldByName('Field3').AsString,
MyQuery.FieldByName*'Field4').AsString,
MyQuery.FieldByName('Field5').AsString,
MyQuery.FieldByName('Field6').AsString],
[EstReading]);
MyQuery.Next;
end;
end
Run Code Online (Sandbox Code Playgroud)
Dav*_*nan 12
您没有正确处理动态分配的记录.您的记录是受管理的,因为它包含托管类型,在这种情况下为字符串.
管理类型,当像这样动态分配时,需要分配New和解除分配Dispose.你的错误是使用FreeMem而不是Dispose.后者将在记录中处理托管类型,前者不会.因此你的泄漏.
看起来可能ClearTList存在同样的缺陷.
您将指针存储在TList实例中,此类型存储无类型指针.处理每个项目时,必须将项目转换回适当的指针类型,以便运行时知道如何处理记录中的字段.所以你的电话Dispose会是这样的:
Dispose(PrintPointer(List[I]));
Run Code Online (Sandbox Code Playgroud)
另外,在调用时传递元素的大小FreeMem是没有意义的.
总结一下:
GetMem/FreeMem,或New/Dispose.New/Dispose.FreeMem与GetMem,永远Dispose在一起New.