Delphi 提供 finally 保留字確保資源釋放:
{ 配置資源 }
try
{ 資源使用 }
finally
{ 釋放資源 }
end;
try...finally...end 形成資源保護區塊。finally 區塊在任何情況下(無論是否發生異常)必定執行。
修正 12.2.1 節會造成 1K 記憶體洩漏的程式:
var
APointer: Pointer;
AInt, ADiv: Integer;
begin
ADiv := 0;
GetMem(APointer, 1024);
try
AInt := 10 div ADiv; { 觸發 EDivByZero }
finally
FreeMem(APointer, 1024); { 異常發生也必定執行 }
end;
end;
節錄自第 6.4 節,展示三層巢狀 try...finally 保護緩衝區、來源檔、目的檔三種資源:
procedure CopyFile(const FileName, DestName: TFileName);
var
CopyBuffer: Pointer;
TimeStamp, BytesCopied: Longint;
Source, Dest: Integer;
Destination: TFileName;
const
ChunkSize: Longint = 8192;
begin
Destination := ExpandFileName(DestName);
if HasAttr(Destination, faDirectory) then
Destination := Destination + '\' + ExtractFileName(FileName);
TimeStamp := FileAge(FileName);
GetMem(CopyBuffer, ChunkSize);
try
Source := FileOpen(FileName, fmShareDenyWrite);
if Source < 0 then
raise EFOpenError.Create(FmtLoadStr(SFOpenError, [FileName]));
try
Dest := FileCreate(Destination);
if Dest < 0 then
raise EFCreateError.Create(FmtLoadStr(SFCreateError, [Destination]));
try
repeat
BytesCopied := FileRead(Source, CopyBuffer^, ChunkSize);
if BytesCopied > 0 then
FileWrite(Dest, CopyBuffer^, BytesCopied);
until BytesCopied < ChunkSize;
finally
FileClose(Dest);
end;
finally
FileClose(Source);
end;
finally
FreeMem(CopyBuffer, ChunkSize);
end;
end;
內層保護目的檔控制代碼,中層保護來源檔控制代碼,外層保護記憶體緩衝區。任何層級發生異常,外層 finally 依序執行確保資源釋放。
異常發生時,系統自動彈出訊息框顯示異常訊息。退出當前區塊後異常類別自動清除。