当我在未初始化的函数结果上调用方法时,为什么不能获得访问冲突?

时间:2012-11-20 14:38:28

标签: delphi delphi-xe

我的一位同事向我展示了用Delphi-XE XE版本15.0.3953.35171编写的代码,我认为它应该引发访问冲突。代码如下:

unit Unit3;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TForm3 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
   function test:TstringList;
    { Public declarations }
  end;

var
  Form3: TForm3;

implementation

{$R *.dfm}

procedure TForm3.FormCreate(Sender: TObject);
var aStrList : TStringList;
begin
 aStrList := TStringList.Create;
 test;
 FreeAndNil(aStrList);
end;

function TForm3.test: TstringList;
var i:Integer;
begin
 for i:=0 to 1000 do
  Result.Add('aaa');//AV?
end;

end.

检查aStrList和Result具有以下结果:

aStrList: TStringList $12FEDC : $42138A


Result: TStringList $12FEC4 : $B01B90

我不明白它为什么会起作用。 Result.Add应该引发访问冲突

LE:似乎只适用于Debug Build Configuration。

1 个答案:

答案 0 :(得分:3)

该函数中的Result变量尚未初始化,可以保存任何值。现在,实现细节意味着,在编译器选项的某些组合中,您的代码恰好与引用有效对象的Result一起运行。但这实际上只是这些实施细节的巧合。

如果这是C ++,那么该函数将展示未定义的行为。尽管该术语在Delphi中没有正式含义,但在Delphi设置中使用该术语与C ++语境中的术语相同可能会有所帮助。

我还要指出,即使Result没有引用有效的字符串列表对象,也不能保证代码不会引发访问冲突。可能是Result指向一块内存块,它恰好看起来像一个字符串列表,可以成功执行该代码。

如果您正确地执行操作,则可以预测程序的行为。如果您的代码存在缺陷并导致未定义的行为,那么您的程序行为将变得不可预测。它可能会奏效。它可能会失败。或者该代码可以正常执行,但随后会导致程序执行失败。等等。