ZDecompressStream()导致内存泄漏

马克·潘诺维奇

我一直在使用ZLib函数来压缩/解压缩内存中的流。万一我尝试解压缩无效的流,它将泄漏内存。以下代码将泄漏内存:

uses
  Winapi.Windows, System.Classes, System.ZLib;

function DecompressStream(const AStream: TMemoryStream): Boolean;
var
  ostream: TMemoryStream;
begin
  ostream := TMemoryStream.Create;
  try
    AStream.Position := 0;

    // ISSUE: Memory leak happening here
    try
      ZDecompressStream(AStream, ostream);
    except
      Exit(FALSE);
    end;

    AStream.Clear;
    ostream.Position := 0;
    AStream.CopyFrom(ostream, ostream.Size);
    result := TRUE;
  finally
    ostream.Free;
  end;
end;

var
  s: TMemoryStream;

begin
  ReportMemoryLeaksOnShutdown := TRUE;

  s := TMemoryStream.Create;
  try
    DecompressStream(s);
  finally
    s.Free;
  end;
end.

TMemoryStream在这里尝试将其解压缩为空,并在执行结束时显示发生了内存泄漏。在Delphi XE2上进行测试。

关于如何防止这种泄漏发生的任何想法,因为在现实世界中,我的应用程序有机会尝试对无效流进行解压缩并泄漏那里的内存。

QC:http : //qc.embarcadero.com/wc/qcmain.aspx?d=120329-声称已从XE6开始修复

戴维·赫弗南

这是Delphi RTL代码中的错误。实施ZDecompressStream引发异常,然后无法进行整理。让我们看一下代码:

procedure ZDecompressStream(inStream, outStream: TStream);
const
  bufferSize = 32768;
var
  zstream: TZStreamRec;
  zresult: Integer;
  inBuffer: TBytes;
  outBuffer: TBytes;
  inSize: Integer;
  outSize: Integer;
begin
  SetLength(inBuffer, BufferSize);
  SetLength(outBuffer, BufferSize);
  FillChar(zstream, SizeOf(TZStreamRec), 0);

  ZCompressCheck(InflateInit(zstream));   <--- performs heap allocation

  inSize := inStream.Read(inBuffer, bufferSize);

  while inSize > 0 do
  begin
    zstream.next_in := @inBuffer[0];
    zstream.avail_in := inSize;

    repeat
      zstream.next_out := @outBuffer[0];
      zstream.avail_out := bufferSize;

      ZCompressCheck(inflate(zstream, Z_NO_FLUSH));

      // outSize := zstream.next_out - outBuffer;
      outSize := bufferSize - zstream.avail_out;

      outStream.Write(outBuffer, outSize);
    until (zstream.avail_in = 0) and (zstream.avail_out > 0);

    inSize := inStream.Read(inBuffer, bufferSize);
  end;

  repeat
    zstream.next_out := @outBuffer[0];
    zstream.avail_out := bufferSize;

    zresult := ZCompressCheck(inflate(zstream, Z_FINISH));

    // outSize := zstream.next_out - outBuffer;
    outSize := bufferSize - zstream.avail_out;

    outStream.Write(outBuffer, outSize);
  until (zresult = Z_STREAM_END) and (zstream.avail_out > 0);

  ZCompressCheck(inflateEnd(zstream));   <--- tidy up, frees heap allocation
end;

我从XE3中获取了此信息,但我相信在所有版本中它基本上都是相同的。我强调了这个问题。调用会inflateInit在堆外分配内存。它需要与调用配对inflateEnd因为ZCompressCheck面对错误会引发异常,所以inflateEnd永不会发生调用因此,代码泄漏。

使用try / finally可以正确保护该单元中inflateInit的其他调用inflateEnd这似乎是在此函数中的使用是错误的。

我的建议是,Zlib用正确实施的版本替换设备。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

QProcess导致内存泄漏

来自分类Dev

IOPSCopyPowerSourcesInfo()导致的内存泄漏

来自分类Dev

NSRunAlertPanel导致内存泄漏

来自分类Dev

fork() 导致内存泄漏

来自分类Dev

内存泄漏如何导致信息泄漏?

来自分类Dev

数组或CGImageRef导致内存泄漏

来自分类Dev

FigureCanvasTkAgg的声明导致内存泄漏

来自分类Dev

Cupy fft导致内存泄漏?

来自分类Dev

Android runOnUiThread导致内存泄漏

来自分类Dev

Cupy fft导致内存泄漏?

来自分类Dev

Android runOnUiThread导致内存泄漏

来自分类Dev

这会导致内存泄漏吗?

来自分类Dev

C ++ for循环导致内存泄漏?

来自分类Dev

FigureCanvasTkAgg的声明导致内存泄漏

来自分类Dev

CALayer 导致 ARC 内存泄漏

来自分类Dev

这会导致内存泄漏吗

来自分类Dev

这会导致c ++中的内存泄漏吗?

来自分类Dev

MySQL库导致的Java内存泄漏

来自分类Dev

异步代码会导致内存泄漏吗?

来自分类Dev

位图导致设备上的内存泄漏

来自分类Dev

NavigableMap的subMap会导致内存泄漏吗?

来自分类Dev

为什么QApplication会导致内存泄漏?

来自分类Dev

MySQL库导致的Java内存泄漏

来自分类Dev

PHP扩展中的malloc导致内存泄漏

来自分类Dev

由于Spring单例导致内存泄漏

来自分类Dev

类方法中的alloc导致内存泄漏?

来自分类Dev

来自文件的ObjectInputStream导致内存泄漏

来自分类Dev

zlib inflateReset导致内存泄漏(不是)

来自分类Dev

NSStream.getStreamsToHostWithName导致内存泄漏