2010-11-18 1 views
1

Imが作成セクションに次のコードデルファイアクセス違反読書オブジェクトは

var 
List: TStrings; 

と、次の

Access violation at address 00404340 in module 'test.exe'. Read of address FFFFFFD5

を取得します:
Result := List.AddObject('hi', aCreatedObject); MessageDlg(FunctionHookList.Objects[Result].ClassName, mtInformation, [mbOK], 0);

メッセージダイアログが正しいクラス名

を示ししかし、その後、私が行うとき、

i := list.IndexOf('hi'); 
    if i >= 0 then 
     if list.Objects[i] <> nil then 
     if assigned(list.Objects[i]) then 
      begin 
      tmp := list.Objects[i]; 
      if tmp <> nil then 
       MessageDlg(tmp.ClassName, mtInformation, [mbOK], 0); //******* 
      end; 

私は//*******ライン

上で、上記のアクセス違反を取得し、私が知っていますそこに重複したコードが少しありましたが、私は「すべて」をチェックしようとしていました

+1

「後で」と言ったらどういう意味ですか?おそらく、aCreatedObjectがその時点で破棄され、list.Objects [i]が無効なオブジェクトを返すことがあります。変数宣言を含む完全な関数の中に例を投稿してください。 – Ozan

+0

インデックスiのオブジェクトがnilの場合はコードが2回、割り当てられている場合は1回チェックされます。 Objects [i]をtmpに一度割り当て、tmp: 'if i> = 0をチェックしてtmp:= Objects [i]を開始することができます。もしAssigned(tmp)then ... ... ' – mjn

+0

@Ozan、aCreatedObjectが破壊されている可能性があります。私は '<> nil'と' assigned'の使用がそれを捕まえると思っていました。 –

答えて

1

を割り当てられたことゼロを除き、何もチェックしませんのでご注意ください。文字列リストにオブジェクトを置いて解放し、文字列リストをチェックすると、まだオブジェクトがあることがわかります。次の例を確認してください:

var 
    o: TObject; 
begin 
    o := TObject(42 {just a random number}); 
    if Assigned(o) then 
    ShowMessage(o.ClassName); 
end; 

ほとんどのチェックは有効です。これは、オブジェクトにnil以外の値が含まれているかどうかをチェックするだけです。これは、基本的に上記の行と同じチェックです。

2

プログラムがヌルポインタの負のオフセットから読み込んでいるようです。オフセットは、オブジェクトがそのVMTポインタを格納するフィールドがそのクラスのVMTの実際のアドレスではなくアドレス1を保持することを示唆している、VMTに格納されているクラス名のオフセットから1だけずれています。

実際にそのリストに有効なオブジェクト参照が格納されているかどうかは疑問です。 Listに何かを追加していますが、それが正常に機能することをテストするために、FunctionHookListにオブジェクトの値ClassNameを印刷しています。それらが同じ目的であると信じるには、どのような理由がありますか?オブジェクトの構築方法を確認し、aCreatedObject変数に値を与える代入ステートメントを確認します。間違った宛先ポインタまたは間違ったバイト数を指定してオブジェクトの一部を上書きするような、MoveまたはTStream.Readの呼び出しのような疑わしいメモリ操作を探します。

何が起きているのかを知るには、リスト内のオブジェクトの関数を呼び出します。オブジェクト参照に格納されているポインターがのどこかにある限り、の値が有効ではないかもしれませんが、少なくともそれはクラッシュしないため、一般に安全です。結果はクラスにあります。がリストにあるとします。あなたがリストにTFontを格納した場合、このテスト:

tmp := list.Objects[i]; 
if tmp.ClassType <> TFont then 
    ShowMessage(Format('Expected %p but got %p instead', 
    [Pointer(TFont), Pointer(tmp.ClassType)])); 
関連する問題