The following code creates a .zip
file containing a text file named HelloWord.txt
. Later, it reads the file correctly, but a memory leak occurs using procedure Zipfile.Read (0, LStream, ZHeader)
and releasing LStream
.
I am using ReportMemoryLeaksOnShutdown := DebugHook <> 0;
to see memory leaks.
// Uses System.zip, System.IOUtils;
procedure Probezip;
var
zipfile : TZipFile;
PathDoc : string;
LStream : TStream;
ZHeader : TZipHeader;
MyList : TStringList;
begin
// (Path documents windows)
PathDoc := TPath.GetDocumentsPath;
zipfile := TZipFile.Create;
MyList := TStringList.Create;
try
// Write test TZipfile
MyList.Add ('Hello Word');
MyList.SaveToFile (PathDoc + '\' + 'helloword.txt');
zipfile.Open (PathDoc + '\' + 'test.zip', zmWrite);
ZipFile.Add (PathDoc + '\' + 'helloword.txt');
ZipFile.Close;
MyList.Clear;
// Read test Tzipfile
zipfile.Open (PathDoc + '\' + 'test.zip', zmRead);
LStream := TStream.Create; //This line should be removed to solve the
// problem as Andreas Rejbrand has pointed out.
// I leave it here as a didactic value.
try
zipfile.Read (0, LStream, ZHeader);
MyList.LoadFromStream (LStream);
Showmessage (MyList.Text); // Hello Word
finally
LStream.Free;
end;
finally
zipfile.Close;
zipfile.Free;
MyList.Free;
end;
end;
The second parameter of the TZipFile.Read
overload you are using is of type TStream
, but it is an out
parameter.
This means that the TZipFile.Read
method creates a stream object and makes LStream
point to it. Hence, you leak the stream you created manually on the line before. Remove that line (LStream := TStream.Create;
) and move down the try
protecting the stream:
zipfile.Read(0, LStream, ZHeader); // will CREATE a stream object
// and save its address in LStream
try
MyList.LoadFromStream(LStream);
Showmessage(MyList.Text); // Hello Word
finally
LStream.Free;
end;