加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – 在函数中引发异常时,TStrings返回为“Inaccessible va

发布时间:2020-12-15 09:30:26 所属栏目:大数据 来源:网络整理
导读:有人可以帮助我解释为什么在底层函数中引发异常时,TStrings被返回为“无法访问的值”吗? function GetStrings():TStrings;begin result := TStringList.Create; try raise exception.Create('Error Message'); except FreeAndNil(result); raise end;end;pr
有人可以帮助我解释为什么在底层函数中引发异常时,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;

如果我不调用FreeAndNil(result),函数GetStrings也会返回“Inaccessible value”;在重新启动例外之前.但是,我手上也有内存泄漏:-O

解决方法

try
  S := GetStrings; 
  try
    //Do awesome stuff
  finally
    FreeAndNil(S)
  end;
except
  //Debug watch: S = "Inaccessible value"
  Assert(S = nil,S should be nil'); 
end;

这是执行的顺序:

>由于S是局部变量,因此在初始化之前,其值是不确定的.这是该代码开始执行时的状态.
>调用GetStrings函数.
> GetStrings中引发异常.这意味着GetStrings不会将执行返回给调用者,因此具有从未分配S的结果.
> finally块不会执行,因为它的尝试从未到达.
>接下来,执行except块,并且S具有不确定的值,这是您观察到的.

实际上,编译器应警告(W1036)在except块中引用S时可能尚未初始化S.但它似乎无法做到这一点,这是相当可悲的.

如果您希望能够在您的except块中引用S,则需要将其嵌入try / finally中.

S := GetStrings; 
try
  try
    //Do awesome stuff
  except
    //Do stuff with S
    Assert(S <> nil);
  end;
finally
  FreeAndNil(S)
end;

另一种思考方式是S仅在分配给S的代码和销毁该对象的代码之间有意义.结果是try / except必须嵌套在try / finally中,如果except块将能够引用该对象.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读