Подтвердить что ты не робот

Почему бы мне не получить нарушение доступа, когда я вызываю методы на результат неинициализированной функции?

Один из моих коллег показывает мне код, написанный в Delphi-XE XE Version 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.

4b9b3361

Ответ 1

Переменная Result в этой функции не была инициализирована и может содержать любое значение. Теперь деталь реализации означает, что в некоторых комбинациях параметров компилятора ваш код запускается с Result, ссылаясь на действительный объект. Но это действительно просто совпадение этих деталей реализации.

Если это был С++, тогда эта функция будет демонстрировать поведение undefined. Хотя этот термин не имеет формального значения в Delphi, может оказаться полезным использовать этот термин в настройке Delphi для обозначения того же самого, что и в контексте С++.

Я также хотел бы подчеркнуть, что даже если Result не ссылался на действительный объект списка строк, ваш код не гарантировал бы повысить нарушение доступа. Возможно, что Result указывает на блок памяти, который просто выглядит достаточно, как список строк для успешного выполнения этого кода.

Если вы все сделаете правильно, вы можете предсказать поведение вашей программы. Если ваш код испорчен и вызывает поведение undefined, то поведение вашей программы становится непредсказуемым. Это может сработать. Он может потерпеть неудачу. Или этот код может выполняться нормально, но затем приведет к сбою позже в выполнении программы. И так далее.