SCA*_*son 1 delphi memory-leaks delphi-7
附件是我遇到的内存泄漏示例的完整代码.有人可以告诉我如何清理这个内存泄漏.如果您创建一个表单并在其上放置一个按钮,然后将下面的代码粘贴到.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.
Run Code Online (Sandbox Code Playgroud)
处理每个项目时,运行时需要知道记录的类型.因为你正在使用a TList
然后每个项目是一个无类型指针.因此,您需要将指针强制转换为项类型,以便运行时知道类型,并知道如何处置该项.
更换
Dispose(List[I]);
Run Code Online (Sandbox Code Playgroud)
同
Dispose(PrintPointer(List[I]));
Run Code Online (Sandbox Code Playgroud)
将列表作为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;
Run Code Online (Sandbox Code Playgroud)
更传统的命名约定是:
type
TPrintRecord = record
....
end;
PPrintRecord = ^TPrintRecord;
Run Code Online (Sandbox Code Playgroud)
OnClose
如果表单caHide
在关闭时具有操作,则可以多次调用表单的事件.与之配对的正确事件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;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
484 次 |
最近记录: |