11

同僚の 1 人が、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 でのみ動作しているようです。

4

1 に答える 1

3

そのResult関数の変数は初期化されておらず、任意の値を保持できます。さて、実装の詳細は、コンパイラ オプションのいくつかの組み合わせで、コードがたまたまResult有効なオブジェクトを参照して実行されることを意味します。しかし、それは実装の詳細の単なる偶然です。

これが C++ の場合、その関数は未定義の動作を示します。その用語は Delphi では正式な意味を持ちませんが、Delphi の設定でその用語を使用すると、C++ のコンテキストと同じ意味になる場合があります。

また、有効な文字列リスト オブジェクトを参照していない場合でもResult、コードでアクセス違反が発生する保証はありません。Resultそのコードが正常に実行されるには、たまたま文字列リストのように見えるメモリ ブロックを指している可能性があります。

適切に実行すれば、プログラムの動作を予測できます。コードに欠陥があり、未定義の動作を引き起こす場合、プログラムの動作は予測不能になります。それはうまくいくかもしれません。失敗する場合があります。または、そのコードは正常に実行されても、プログラムの実行の後半で失敗する可能性があります。等々。

于 2012-11-20T19:30:07.790 に答える