次のようなコードで、Delphi 7 アプリケーション (CLX) でメモリ リークの問題が発生しました。
unit Unit2;
interface
uses ECRClass, ECR_Text, SysUtils, Types, Classes, Variants, Math;
type tLeakClass = class
private
fsType : integer;
public
fsPrinter : TECR_Class;
published
constructor Create (AOwner : TComponent);
destructor Destroy();
end;
implementation
constructor tLeakClass.Create (AOwner : TComponent);
begin
fsPrinter := TECR_Text.Create(AOwner);
end;
destructor tLeakClass.Destroy();
begin
fsPrinter.Free
end;
end.
fsPrinter
メインフォーム(TForm)が閉じた瞬間に解放されても、オブジェクトの結果がリークしました:
unit Unit1;
interface
uses
SysUtils, Types, Classes, Variants, QTypes, QGraphics, QControls, QForms,
QDialogs, QStdCtrls, Unit2;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
tleak : tLeakClass;
end;
var
Form1: TForm1;
implementation
{$R *.xfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
tLeak := tLeakClass.Create(Self);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
tleak.Free
end;
end.
FastMM4 によるリークのレポートは次のとおりです。
A memory block has been leaked. The size is: 740
This block was allocated by thread 0xBA8, and the stack trace (return addresses) at the time was:
402F1C [system.pas][System][@GetMem][2439]
403C77 [system.pas][System][TObject.NewInstance][8360]
404012 [system.pas][System][@ClassCreate][9019]
502F15 [ECR_Text.pas][ECR_Text][TECR_Text.Create][101]
403C80 [system.pas][System][TObject.NewInstance][8360]
404012 [system.pas][System][@ClassCreate][9019]
5030C6 [Unit2.pas][Unit2][tLeakClass.Create][24]
43856C [QStdCtrls.pas][QStdCtrls][2863]
503300 [Unit1.pas][Unit1][TForm1.Button1Click][30]
447076 [QControls.pas][QControls][TControl.Click][1977]
43858C [QStdCtrls.pas][QStdCtrls][TButton.Click][2871]
The block is currently used for an object of class: TECR_Text
ここで、問題を表すプロジェクトの完全なSSCCEサンプルをダウンロードできます(サンプルを実行するには、ボタンをクリックしてフォームを閉じます)。
fsPrinter
オブジェクトがリークするのはなぜですか? どうすればリークを回避できますか?