内存泄漏读取 TZipFile

Memory leak reading TZipFile

以下代码创建一个 .zip 文件,其中包含一个名为 HelloWord.txt 的文本文件。后来,它正确读取文件,但是发生内存泄漏 using procedure Zipfile.Read (0, LStream, ZHeader) and releasing LStream.

我正在使用 ReportMemoryLeaksOnShutdown := DebugHook <> 0; 查看内存泄漏。

// 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;

您正在使用的 TZipFile.Read 重载的第二个参数是 TStream 类型,但它是一个 out 参数

这意味着 TZipFile.Read 方法 创建 一个流对象并使 LStream 指向它。因此,您泄漏了之前在线上手动创建的流。删除该行 (LStream := TStream.Create;) 并向下移动 try 保护流:

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;