2010-11-18 30 views
1

Im oluştur Bölümde Aşağıdaki koduDelphi Erişim ihlali Okuma Nesne

var 
List: TStrings; 

ile aşağıdaki

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

alma :
Result := List.AddObject('hi', aCreatedObject); MessageDlg(FunctionHookList.Objects[Result].ClassName, mtInformation, [mbOK], 0);

İleti iletişim

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; 

i //******* hattında yukarıda

Orada olduğunu biliyorum Erişim ihlali olsun

Ama daha sonra benim yaptığım zaman, doğru SinifAdi gösterir bir çift kopyalanmış kod var ama 'her şey' kontrol etmeye çalışıyordum '

+1

"Sonra" derken ne demek istiyorsun?Belki bir theCreatedObject o anda ve list.Objects [i] geçersiz bir nesne döndürür. Lütfen değişken bildirimlerle tam bir işlev içinde bir örnek gönderin. – Ozan

+0

kodunuz, i indeksindeki nesne nil ise iki kez kontrol edilir ve atanırsa bir kez. Bir kez tmp yapmak için Nesneleri [i] atayabilir ve tmp'yi kontrol edebilirsiniz: 'i i = = 0 sonra tmp: = Objects [i]; Atanmış (tmp) o zaman ... ' – mjn

+0

@Ozan, aCreatedObject öğesinin imha edilmiş olabileceği düşünülüyordu, '

cevap

1

için nil dışında bir şey kontrol etmez Atanan unutmayınız. Dize listesine bir nesne koyarsanız, boşaltır ve ardından dize listesini kontrol ederseniz, hala bir nesne olduğunu söyler. Şu örneği kontrol edin:

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

Atananlar dışında hemen hemen tüm çekleriniz geçerlidir. Yalnızca, nesnenin nil'den başka bir değer içerip içermediğini kontrol eder, ki bu temelde yukarıdaki satırda yaptığınız aynı kontrolü içerir.

2

Programınız boş göstericinin negatif bir ofsetinden okuyor gibi görünüyor. Ofset, VMT'de saklanan sınıf adının bulunduğu ofsetin bir tanesidir ve nesnenin VMT işaretçisini sakladığı alanın, sınıfının VMT'sinin gerçek adresi yerine 1 adresini tuttuğunu gösterir. Bu listede geçerli bir nesne başvurusunu gerçekten depolayıp saklamadığınızı sorgular. List'a bir şey ekliyorsunuz, ancak çalışıp çalışmadığını test etmek için FunctionHookList'da bazı nesnelerin ClassName değerini yazdırıyorsunuz. Bunların aynı nesne olduğuna inanmak için ne sebep var? Nesneyi nasıl oluşturduğunuzu kontrol edin ve sonra aCreatedObject değişkenine bir değer veren atama deyimini kontrol edin. Move veya TStream.Read numaralı aramaların yanlış hedef işaretçisi veya yanlış bir bayt sayımı belirttiğiniz gibi sorgulanabilir bellek işlemlerine bakın, böylece nesnenin bir bölümünü üzerine yazarak.

Neler olup bittiğini öğrenmek için, listedeki nesnede ClassType işlevini çağırın. (Bu genellikle çağırmak için güvenlidir, çünkü işaretçi nesne referans noktalarında bir yerde saklandığı sürece, bir değer elde edersiniz. Belki geçerli değeri, ancak en azından çökmeyecektir.) Sonuç olarak, sınıfının listeye girmesi için olmasını beklersiniz. Örneğin, eğer listedeki bir TFont saklanan, o zaman bu testi:

tmp := list.Objects[i]; 
if tmp.ClassType <> TFont then 
    ShowMessage(Format('Expected %p but got %p instead', 
    [Pointer(TFont), Pointer(tmp.ClassType)])); 
İlgili konular