[英]Improper exception handling / object freeing probably causes memory leak (Cause: unnoticed “variable might not be assigned” warning)
我已將所有內容移至單個EXE
var SenderInstance: AutoGeneratedWebserviceUnit.Sender;
...
procedure TForm1.FormCreate(Sender: TObject);
begin
SenderInstance := AutoGeneratedWebserviceUnit.GetSender(False, 'http://invalid_URL'); // => there is no exception here
end;
...
procedure TForm1.Button1Click(Sender: TObject);
var
req: AutoGeneratedWebserviceUnit.Request;
res: AutoGeneratedWebserviceUnit.Response;
begin
try
req := Request.Create;
try
with req do
begin
ID := 0;
param := 'trash';
end;
res := SenderInstance.Request('Login', 'Pass', req); // => ESOAPHTTPException + EAccesViolation !
ShowMessage(res.status);
finally
req.Free;
res.Free; // ### MOST POSSIBLE PROBLEM CAUSE ###
end;
except
on E: Exception do
ShowMessage(E.Message);
end;
end;
我了解ESOAPHTTPException, 但是AV? 為什么? ...
引發ESOAPHTTPException之后發生奇怪的事情... 我想是我無法弄清內存泄漏之類的東西,或者我做了一些真正愚蠢的事情...
有設置嗎? 也許我忘記了什么?
我發現了一些關於“ res.Free;”的東西。 try / finally塊內的行禁用此行不會導致任何AV,但是Assigned(req)返回True Assigned(res)也返回True ...
什么...?
導致AV的問題在於Button1Click
事件處理程序中的try..finally
子句。
您正在試圖釋放你的res
變量(響應), 尚未分配的任何東西,因為在調用Request
方法失敗並拋出異常。 這意味着它包含垃圾並通過調用res.Free
來訪問您不應該訪問的內存位置,這可能會引發幾乎任何奇怪的錯誤。
為了解決它,在進入try..finally
之前將res設置為nil
,並在調用res.Free
之前檢查是否已分配它。
附帶一提,這是因為res
是局部變量。 如果它將是類實例的成員 ,則編譯器將自動為其分配一個nil
值。
更新
正如@RobKennedy所說的,使用嵌套的 try..finally
塊要比我首先告訴您的nil
更好(如果某些析構函數失敗,可能會導致問題)。
因此,您將執行以下操作:
req := Request.Create;
try
req.ID := 0;
req.param := 'trash';
res := SenderInstance.Request('Login', 'Pass', req);
try
ShowMessage(res.status);
finally
res.Free;
end;
finally
req.Free;
end;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.