gpt4 book ai didi

delphi - 使用 tlist 的完整 Delphi 代码中的内存泄漏

转载 作者:行者123 更新时间:2023-12-03 19:14:33 24 4
gpt4 key购买 nike

附件是我遇到的内存泄漏示例的完整代码。有人可以告诉我如何清理这个内存泄漏。如果您创建一个表单并在其上放置一个按钮,然后将以下代码粘贴到 .pas 文件中,则可以编译此代码。提前感谢您提供的任何帮助。

unit LeakForm;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type PrintRecord = record
PrintString1,
PrintString2,
PrintString3,
PrintString4,
PrintString5,
PrintString6 : string;
PrintFloat1,
PrintFloat2,
PrintFloat3 : Double;
end;
PrintPointer = ^PrintRecord;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
MyPrintLst : TList;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}
procedure ClearTList(Var List : TList);
Var I, Count : Integer;
begin
Count := list.Count - 1;
For I := Count DownTo 0 Do
Dispose(List[I]);
List.Clear;
end;
procedure FreeTList(Var List : TList);
Var I, Count : Integer;
begin
ClearTList(List);
List.Free;
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 TForm1.Button1Click(Sender: TObject);
Var EstReading : LongInt;
begin
EstReading := 0;
ClearTList(MyPrintLst);
AddToPrintList(MyPrintLst, ['Field1 Data','Field2 Data','Field3 Data','Field4 Data'],
[1,2,3,4]);
AddToPrintList(MyPrintLst, ['Field1 Data','Field2 Data','Field3 Data','Field4 Data'],
[5,6,7,8]);
AddToPrintList(MyPrintLst, ['Field1 Data','Field2 Data','Field3 Data','Field4 Data'],
[9,0,1,2]);
AddToPrintList(MyPrintLst, ['Field1 Data','Field2 Data','Field3 Data','Field4 Data'],
[3,4,5,6]);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
MyPrintLst := TList.Create;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
FreeTList(MyPrintLst);
end;

end.

最佳答案

当您处理每个项目时,运行时需要知道记录的类型。因为您使用的是 TList那么每个项目都是一个无类型的指针。因此,您需要将指针转换为项目类型,以便运行时知道类型,并知道如何处置项目。

代替

Dispose(List[I]);


Dispose(PrintPointer(List[I]));

您将列表作为 var 参数传递并且不修改引用也有点奇怪。而且循环也很奇怪,无缘无故地向后运行,并且循环边界以一种奇怪的方式处理。我会有这样的功能:
procedure ClearTList(List: TList);
Var
I: Integer;
begin
For I := 0 to List.Count - 1 Do
Dispose(PrintPointer(List[I]));
List.Clear;
end;

procedure FreeTList(List: TList);
begin
ClearTList(List);
List.Free;
end;

更传统的命名约定是:
type
TPrintRecord = record
....
end;
PPrintRecord = ^TPrintRecord;

表格的 OnClose如果表单具有 caHide,则可以多次调用事件。关闭时的 Action 。与 OnCreate 配对的正确事件是 OnDestroy .
AddToPrintList 中的逻辑复杂度让我相信可以以更好的方式设计数据类型。数组建议自己而不是单个编号的字段。

在不更改类型的情况下,您至少应该避免所有缩进,如下所示:
procedure AddToPrintList(PrintList: TList; const MyStrings: array of String;
const MyDoubles: array of Double);
var
I: Integer;
Item: PPrintRecord;
Str: string;
Value: Double;
begin
New(Item);
PrintList.Add(Item);

for I := 1 to Min(Length(MyStrings), 6) do
begin
Str := MyStrings[I - 1];
case I of
1:
Item.PrintString1 := Str;
2:
Item.PrintString2 := Str;
3:
Item.PrintString3 := Str;
4:
Item.PrintString4 := Str;
5:
Item.PrintString5 := Str;
6:
Item.PrintString6 := Str;
end;
end;

for I := 1 to Min(Length(MyDoubles), 3) do
begin
Value := MyDoubles[I - 1];
case I of
1:
Item.PrintFloat1 := Value;
2:
Item.PrintFloat2 := Value;
3:
Item.PrintFloat3 := Value;
end;
end;
end;

关于delphi - 使用 tlist 的完整 Delphi 代码中的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33742315/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com