2016-12-25 49 views
-3

我有一個記錄,它看起來像這樣:的Delphi TPngImage存儲器泄漏

TCell = record 
    Marked:  Boolean; 
    ToBeMarked: Boolean; 
    Image:  TPngImage; 
    end; 

var Cells: array of array of TCell 

細胞一定程序期間創建[n]的圖像配,然後被存儲供以後使用。每次調用該過程時,都會清除該數組。 但是,關閉程序後仍然有內存泄漏報告。

unit Unit1; 

interface 

uses 
    Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, 
    Vcl.Controls, Vcl.Forms, Vcl.Dialogs, pngimage, Vcl.StdCtrls; 

type 
TCell = record 
    Marked:  Boolean; 
    ToBeMarked: Boolean; 
    Image:  TPngImage; 
    end; 
    TForm1 = class(TForm) 
    Button1: TButton; 
    procedure Button1Click(Sender: TObject); 
    procedure TestProcedure1; 
    procedure TestProcedure2(X,Y: Integer); 
    private 
    { Private declarations } 
    public 
    { Public declarations } 
    end; 

var 
    Form1: TForm1; 
    Cells: array of array of TCell; 
    RI_LengthX: Integer; 
    RI_LengthY: Integer; 

implementation 

{$R *.dfm} 

procedure TForm1.Button1Click(Sender: TObject); 
begin 
TestProcedure1; 
end; 

procedure TForm1.TestProcedure1; 
var X,Y: Integer; 
begin 
{ Clearing the array before the new cycle } 
for X:=0 to High(Cells) do for Y:=0 to High(Cells[X]) do  Cells[X,Y].Image.Free; 
SetLength(Cells,0); 
{ Creating new array } 
RI_LengthX:=10; 
RI_LengthY:=10; 
SetLength(Cells,RI_LengthX); 
for X:=0 to High(Cells) do SetLength(Cells[X],RI_LengthY); 
{ Calling the procedure that creates image for every cell } 
for X:=0 to RI_LengthX-1 do for Y:=0 to RI_LengthY-1 do  TestProcedure2(X,Y); 
end; 

procedure TForm1.TestProcedure2(X,Y: Integer); 
var BaseBMP: TBitmap; 
begin 
{ Dynamic creation of an image } 
BaseBMP:=TBitmap.Create; 
BaseBMP.Width:=25; 
BaseBMP.Height:=25; 
{ Saving image inside a record } 
Cells[X,Y].Image:=TPngImage.Create; // Commenting these lines 
Cells[X,Y].Image.Assign(BaseBMP); // prevents the leak 
BaseBMP.Free; 
end; 

initialization 
ReportMemoryLeaksOnShutdown:=True; 

end.` 

enter image description here

是否有避免這種泄漏的方法嗎?

+2

請顯示[MCVE] –

+0

根據Loghman建議改變結算程序和提供的代碼需要最低限度。泄漏仍然存在。 –

+0

請提供[mcve]而不是*「最少需要的代碼」*,無論如何。 –

回答

7

使用SetLength(Cells,0);之前,你必須執行以下代碼

for i := 0 to High(Cells) do 
    Cells[i].Image.Free;