有人可以帮助我解释为什么在底层函数中引发异常时,TStrings被返回为"无法访问的值"吗?
function GetStrings():TStrings;
begin
result := TStringList.Create;
try
raise exception.Create('Error Message');
except
FreeAndNil(result);
raise
end;
end;
procedure TFormMain.Button1Click(Sender: TObject);
var
S : TStrings;
begin
try
S := GetStrings;
try
//Do awesome stuff
finally
FreeAndNil(S)
end;
except
//Debug watch: S = "Inaccessible value"
Assert(S = nil, 'Assertion failure, S should be nil');
end;
end;
Run Code Online (Sandbox Code Playgroud)
GetStrings如果我FreeAndNil(result);在重新引发异常之前没有调用,该函数也会返回"无法访问的值" .但是,我手上也有内存泄漏:-O
try
S := GetStrings;
try
//Do awesome stuff
finally
FreeAndNil(S)
end;
except
//Debug watch: S = "Inaccessible value"
Assert(S = nil, 'Assertion failure, S should be nil');
end;
Run Code Online (Sandbox Code Playgroud)
这是执行的顺序:
S是局部变量,因此在初始化之前,其值是不确定的.这是该代码开始执行时的状态.GetStrings函数被调用.GetStrings.这意味着GetStrings不会将执行返回给调用者,因此具有S从未分配的结果.finally块未执行,因为从未尝试过它.except块执行,并S具有不确定的值,这是您观察到的.实际上,编译器应警告(W1036)S在except块中引用它时可能尚未初始化.但它似乎无法做到这一点,这是相当可悲的.
如果您希望能够S在您的except区块中引用,您将需要将其嵌入到区域中try/finally.
S := GetStrings;
try
try
//Do awesome stuff
except
//Do stuff with S
Assert(S <> nil);
end;
finally
FreeAndNil(S)
end;
Run Code Online (Sandbox Code Playgroud)
另一种思考方式S是只在分配S的代码和销毁对象的代码之间有意义.结果是try/except必须嵌套在内部try/finally,如果except块将能够引用该对象.
| 归档时间: |
|
| 查看次数: |
478 次 |
| 最近记录: |