[英]ZDecompressStream() causes memory leak
我一直在使用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上進行測試。
任何想法如何防止這種泄漏發生,因為在現實世界中,我的應用程序有可能嘗試解壓縮無效流並泄漏內存。
質量控制: 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
的調用會從inflateInit
分配內存。 它需要與對inflateEnd
的調用配對。 因為ZCompressCheck
在遇到錯誤時會引發異常,所以對inflateEnd
的調用永遠不會發生。 因此代碼泄漏。
使用try / finally正確保護該單元中的inflateInit
和inflateEnd
的其他調用。 它似乎只是在這個函數中使用是錯誤的。
我的建議是用正確實現的版本替換Zlib
單元。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.