-1

関係ないかもしれませんが、最近 Delphi XE2 を再インストールしました。

私は変数を持っていますpath(タイプ TPath、TMS Gogole マップのものですが、それが重要であるとは思えません)。

デバッガーで停止しpath、 を評価します。これは として評価されNilます。

実行すると、例外が発生Read of address 0します。これは、これが原因であると思われます。

次に、それが進化するAssigned(path)と同時に評価すると(行で停止したときと同じ結果-実行されます))。path = NilTrueShowMessage

誰かが私にそれを説明できますか?

クリーン&リビルドしても何も変わりません。Delphi を削除して再インストールした方がよいでしょうか?

(@mbratch に謝罪します。varデモに使用しました。実際の名前は実際のものですpath)


[更新] TMS によって提供され、それらのために動作する完全なコード サンプル (別のタイム ゾーンで、ここでも質問する理由です)。

This was retested here with:

 uses
   uwebgmapspolylines;

 procedure TForm1.FormCreate(Sender: TObject);
 var
   p: TPath;
 begin
   p := TPath.Create;

   if Assigned(p) then
     ShowMessage('creation OK');
 end;

and this proves the correct creation of TPath returns a valid instance.

に立ち寄ってif Assigned(p) then評価するpと が得られますNilが、評価するAssigned(p)と が得られTrueます。

IDE で変数宣言の上にカーソルを置くと、型が UWebGMapsPolyLines で宣言されていることが示されます


[さらなる更新] 2 票で締めくくりますか? 真剣に?これはあり得ないと思っている人もいると思いますが、実際にそうです!!!

奇妙なことは、@j がそれを試して を得たということp <> Nilです。ただし、2 台目の PC で試してみましたp = Nilが、TMS から提供された、ここに投稿されたコードを引き続き使用できます。

奇妙に思えるかもしれませんが、2 台の PC で再現できます。P は Nil ですが、Assigned() です。

足を踏み入れる Assigend() のコードがありません。また、コードを明示的にわずかに変更してif System.Assigned(p)も、同じ結果が得られました。助言がありますか?

割り当てられているかどうか?

4

1 に答える 1

2

私はあなたのコードを(Delphi XE2で)正確に使用し、これを見つけました:

TPath ブレークポイント

TPath ウォッチ

あなたはおそらく混乱FOwner = nilしていp = nilますか? TPathから継承するTPersistentため、所有者を渡すことができます (ただし、そうするのはオプションです)。たとえば、次のことができます。

 p := TPath.Create(self);

編集

これを試して :

   var p:TPath
   begin
*1   if assigned(p) then ShowMessage('foo');
     p:=nil;
     if assigned(p) then ShowMessage('bar');
     p:=TPath.Create;
     if assigned (p) then ShowMessage('ok');
   end;

ブレークポイントをオン*1にすると、ウォッチまたはローカル変数ウィンドウに次のように表示されます。

 p       *Inaccessible Value*

参照カウントされていない参照型のローカル変数は、ゼロまたは nil に初期化されません。変数に割り当てられた空間にたまたまあったランダム データが含まれます。 「アクセスできない値」とは、そのランダム データが何であれ、プログラムのメモリ空間内の読み取り可能なメモリ アドレスを指していないことを意味します。

次の行に進む --> 'foo' -->if assigned(p)...

メッセージが表示されます...なぜですか?! Assignedローカル変数が初期化されていないため、 Assignednilは true を返します (初期化されていないローカル変数が指定されていることは認識されません。指定されていないものがあることだけが認識されますnil)。これが、初期化されていないローカル変数を解放するのが悪い考えである理由でもあります。

次の行に進む -- > p := nil -->if assigned(p)...

p:=nil を通過すると、アクセスできない値が次のように変化することがわかります。

 p       nil

また、「bar」というメッセージは表示されません (assigned(p) は のみをチェックすることに注意してnilください)。時計で裸であることに注意してくださいnil-括弧はありません! 最後までステップスルーするとp、ウォッチが作成された後、 の値が再び変化することがわかります。

 p       (nil)     

Sertac がコメントで説明したように、オブジェクトが作成されると、watch/locals ウィンドウにメンバーの内容が括弧内に表示されます。上記は、そうでpはないnil(かっこなし)、初期化されていない(つまり、アクセスできない値FOwnerではない)こと、およびnilに初期化され、割り当てられていないメンバーフィールドも含むこと(展開すると、あることを示します)を示しています価値。

簡単な教訓はAssigned、フィールドまたはグローバルに対してのみ本当に有用であり、参照カウントされていないローカル変数に対しては有用ではないということです。前者はnilオブジェクトの作成時に初期化され、後者はそうではありません (メソッドに入るとき)。

于 2013-06-10T14:18:52.347 に答える