Konuyu Oyla:
  • Derecelendirme: 5/5 - 3 oy
  • 1
  • 2
  • 3
  • 4
  • 5
Pointer Dereferencing Hakkında.
#1
program Project1;

{$APPTYPE CONSOLE}
{$R *.res}

uses
 System.SysUtils;

type

 PNode = ^TNode;

 TNode = record
   Value: Integer;
   Node: Pointer;
 end;

var
 ANode1: TNode;
 ANode2: TNode;
 ANode3: TNode;
 V : Integer;
begin

 ANode3.Value := 31;
 ANode2.Node := @ANode3;
 ANode1.Node := @ANode2;

 V := //?
end.
Yukarıdaki örnek programda V değişkeni üzerine, ANode3.Value üzerindeki değerin okunması istenmektedir.
Fakat doğrudan V := ANode3.Value gibi bir kullanım istenmeyip, ANode1 değişkeni üzerinden erişim sağlanması istenmektedir.

Not : Dileyen yukarıdaki benzer yapıyı ve çözümü C/C++ ile kodlayıp çözüm sunabilir.
Kolay gelsin.
WWW
Cevapla
#2
V := PNode(PNode(ANode1.Node)^.Node)^.Value;

Tabi telefondan değil de bilgisayardan yazıyor olsaydım herbir Node un bir PNode olup olmadığını, Nil olup olmadığını ve derefere edip edemediğimi falan da kontrol ettirirdim...
Me on the move..
WWW
Cevapla
#3
program Project1;

{$APPTYPE CONSOLE}
{$R *.res}

uses
System.SysUtils;

type

PNode = ^TNode;

TNode = record
  Value: Integer;
  Node: Pointer;
end;

var
ANode1: TNode;
ANode2: TNode;
ANode3: TNode;
V : Integer;
begin

ANode3.Value := 31;
ANode2.Node := @ANode3;
ANode1.Node := @ANode2;

asm
  mov eax, DWORD ptr ds:ANode1 + 16
  mov V, eax
end;

Writeln(IntToStr(V));
Readln;

end.
Ayakkabıyı sefaletten
Çok sonraları tanıdım
Öyle ufuklarda mı olurmuş Allah'ım
Giyer giyer koşardım
Toprağın dostluğundan
Oyuncaklar yaptım çamurdan
Tenimin rengini aldım topraktan
Sen bakma esmerliğim sonradan...





Cevapla
#4
program Project1;

{$APPTYPE CONSOLE}
{$R *.res}

uses
System.SysUtils;

type

PNode = ^TNode;

TNode = record
 Value: Integer;
 Node: Pointer;
end;

var
ANode1: TNode;
ANode2: TNode;
ANode3: TNode;
V : Integer;
p1: PNode;
begin

ANode3.Value := 31;
ANode2.Node := @ANode3;
ANode1.Node := @ANode2;
// V := PNode(PNode(ANode1.Node)^.Node)^.Value;  /// The_aLiEn   Çalışıyor
{asm
 mov eax, DWORD ptr ds:ANode1 + 16       ///QuAdR  Çalışıyor
 mov V, eax
end;}

{p1:=PNode(ANode1.Node).Node;
V:=p1.Value;  }                          // Çalışıyor

{
  V:=integer(Pointer(NativeInt(@ANode1) + 16)^);         //çalışıyor
}

{
   V:=integer(Pointer(NativeInt(@ANode1.Node) + 12)^);         //çalışıyor
}
   V:=integer(Pointer(NativeInt(@PNode(ANode1.Node).Node) + 4)^);          //çalışıyor
 Writeln(IntToStr(V));
Readln;

end.
Herhangi bir basit problem, hakkında yeterince toplantı yapılarak, çözümsüz hale getirilebilir.
https://play.google.com/store/apps/developer?id=ONGUN
WWW
Cevapla
#5
program Project1;

{$APPTYPE CONSOLE}
{$R *.res}

uses
 System.SysUtils;

type

 TNode = record
   Value: Integer;
   Node: Pointer;
 end;
 PNode = ^TNode;

var
 ANode1  : TNode;
 ANode2  : TNode;
 ANode3  : TNode;
 V       : Integer;
 p1      : PNode;
 //NOD   : TNode;

begin
 ANode3.Value := 31;
 ANode2.Node := @ANode3;
 ANode1.Node := @ANode2;

 { V := PNode(PNode(ANode1.Node)^.Node)^.Value; }                  // The_aLiEn   Çalışıyor
 { asm mov eax, DWORD ptr ds:ANode1 + 16 mov V, eax end; }         // QuAdR       Çalışıyor
 { p1:=PNode(ANode1.Node).Node; V:=p1.Value; }                     // Savasbd     Çalışıyor
 { V:=integer(Pointer(NativeInt(@ANode1) + 16)^); }                // Savasbd     Çalışıyor
 { V:=integer(Pointer(NativeInt(@ANode1.Node) + 12)^); }           // Savasbd     Çalışıyor
 { V:=integer(Pointer(NativeInt(@PNode(ANode1.Node).Node) + 4)^);} // Savasbd     Çalışıyor

 p1 := PNode(@ANode1);
 while (p1.Node <> nil) do begin
        p1 := PNode(p1.Node);
        if (p1.Node = nil) then V := p1.Value;
        //V := p1.Value;
 end;
 {
 NOD := ANode1;
 while (NOD.Node <> nil) do begin
        NOD := PNode(NOD.Node)^;
        V := NOD.Value;
 end;
 }

 Writeln(IntToStr(V));
 Readln;

end.
YouTube Delphi Tips
"Yaşlanarak değil, yaşayarak tecrübe kazanılır. Zaman insanları değil, armutları olgunlaştırır" Peyami Safa
WWW
Cevapla
#6
Öncelikle değer verip ilgilenen herkese teşekkür ederim.
Benim de ilk çözme yöntemim The_aLiEn hocam'ın gibi oldu.

Alternatif çözüm olsun diye yazıyorum.Fakat kodun anlaşılmasını ve hata ayıklamasını zorlaştırıyor.
program Project1;

{$APPTYPE CONSOLE}
{$R *.res}

uses
 System.SysUtils;

type

 PNode = ^TNode;

 TNode = record
   Value: Integer;
   Node: Pointer;
 end;

var
 ANode1: TNode;
 ANode2: TNode;
 ANode3: TNode;
 V: Integer;
begin
 ANode3.Value := 31;
 ANode2.Node := @ANode3;
 ANode1.Node := @ANode2;

 V := PNode(PPointer(PNode(PPointer(ANode1.Node))^.Node))^.Value;

end.

Benzer şekilde C/C++ çözümü.
#include <iostream>
using namespace std;

typedef void *PVOID;

typedef struct TNode
{
    int Value;
    PVOID Node;

} *PNode;

int main()
{
   int V = 0;
   TNode node1, node2, node3;
   node3.Value = 31;
   node2.Node = &node3;
   node1.Node = &node2;

   V = PNode(PNode(node1.Node)->Node)->Value;

   cout << V << endl;
   return 0;
}
WWW
Cevapla
#7
Naçizane bir şeyler söylemek isterim:

 TNode = record
  Value: Integer;
  Node: Pointer;
end;

asm
 mov eax, DWORD ptr ds:ANode1 + 16
 mov V, eax
end;


  1. Sistemin 32-bit'lik olduğu varsayılmıyor mu? 64-bit'lik olduğunda (ve tabiki ilgili register düzenlemesiyle) +16 bytelık offset doğru adresi point etmeyecek, DWORD ptr ifadesi doğru adresi derefere etmeyecektir.
  2. Record field sırasının değişmeyeceğinin garantisi var mı? Field'ların yerlerini değiştirdiğinizde ya da araya bir başka field eklediğinizde hatalı sonuç üretecektir ya da AV hatası alacaktır.

while (p1.Node <> nil) do
...
if (p1.Node = nil) then V := p1.Value;

Derlenme aşamasında değişkenlerin nil/zero initialization kodlarının yerleştirilmediği durumda, ki derleyici bu initialization kodlarını yerleştirir, sonsuz döngüye girmeye kalkışacak, ilk fırsatta da AV hatası alacaktır. Mesela

ANode3.Node := @ANode1;

ya da

ANode3.Node := Pointer($FFFFFFFF);

Kodun hızlı çalışması hedeflenmeli elbette, ama ya bug-free kalabilmesi? Mevcudu düzeltmek için harcanacak vakitle yeni şeyler üretilebilir böylece.

Şu an adreslemek istediğim iki konu Hard Coding ve Value Checking aslında.

Sürç-ü lisan? Rica ile, affola..
Me on the move..
WWW
Cevapla
#8
Saf pointerler üzerinden gidecek olursak;

ANode3.Node := Pointer($FFFFFFFF);

Bu tarz bir kullanımın kaderi, varacağı yer, her durumda access violation ile sonuçlanmak olacaktır. Böyle kullanılırsa zaten bundan bir kaçış yok, dolayısıyla bu tarz bir sorunla karşılaşmamanın en kolay yolu, daha en baştan o yola sapmamaktan geçer. Öbür türlüsü try except...

{ V := PNode(PNode(ANode1.Node)^.Node)^.Value; }
{ asm
      mov eax, DWORD ptr ds:ANode1 + 16
      mov V, eax
  end; }
{ p1:=PNode(ANode1.Node).Node; V:=p1.Value; }
{ V:=integer(Pointer(NativeInt(@ANode1) + 16)^); }
{ V:=integer(Pointer(NativeInt(@ANode1.Node) + 12)^); }
{ V:=integer(Pointer(NativeInt(@PNode(ANode1.Node).Node) + 4)^);}

Tarzında bir kullanıma gelecek olursak (ki özünde tümü aynı yöntem), o zaman ben de mevcut soruyu şu şekilde bükeyim; "Eleman sayısının belli olmadığı bir durumda" yukarıdaki kodlar bizi sonuca ulaştırır mı?

"Sonsuz döngüden çıkma konusunda" ise aklıma iki alternatif geliyor, ya makul bir sayaç değeri ile döngüden kaçılır (ki eksik bir yol olmuş olur), ya da işlenen her adres daha önceden işlenmiş mi ona bakılır.
YouTube Delphi Tips
"Yaşlanarak değil, yaşayarak tecrübe kazanılır. Zaman insanları değil, armutları olgunlaştırır" Peyami Safa
WWW
Cevapla
#9
 V := PNode(PNode(ANode1.Node).Node)^.Value;

.
Cevapla


Konu ile Alakalı Benzer Konular
Konular Yazar Yorumlar Okunma Son Yorum
  Bağlı Liste & Undocumented API Hakkında (+25 .. +100) Tuğrul HELVACI 22 22.784 06-10-2017, Saat: 22:41
Son Yorum: ismailkocacan
  RTTI PE Hakkında ismailkocacan 5 6.472 23-09-2017, Saat: 00:24
Son Yorum: ismailkocacan



Konuyu Okuyanlar: 1 Ziyaretçi