Quote:
Originally Posted by Norbert8
int iV = 10;
// Zeiger erstellt.
int *Zahl = &iV;
cout << iV << endl; // = 10
cout << Zahl << endl; // Adresse von iV bekommen wie hier
( Ein Zeiger kann uns nur die Adresse sagen, nicht iV. Deswegen geben wir auch aus cout << Zahl << endl; aus....
|
vollkommen unnötig...
es hat relativ wenig damit zu tun, was ich gesagt habe lol.
wenn in der source von warrock ein pointer deklariert ist (z.B. der automatisch erstellte "this"-pointer bei einer class) ist die speicheradresse (kurz addy) ein doppelpointer, d.h. typename**.
habe ich also
Code:
class xxx {
float a;
float b;
};
so kann die adresse des this-pointers ausgelesen werden. dieser ist vom typ xxx* also ist die adresse dahinter vom typ xxx**; um auf den wert a hierdrin zugugreifen muss also der anfangspunkt der class gefunden werden
Code:
#define THIS_PTR 0x123 //nur ein beispiel
DWORD * ptr = (DWORD*)THIS_PTR; // das ist unser this-pointer.
das folgende enthält dann die startadresse der class
um jetzt auf ein element in der class zugreifen zu können, müssen die abstände zu *ptr berechnet werden. diese abstände nennt man offsets.
das offset zu element a ist 0x4, denn es ist gleich zu beginn der class.
das offset zu element b ist 0x4, denn die größe des vorherigen elements ist sizeof(float) == 0x4
mit
Code:
*(float*)(*ptr + 0x4)
kann ich also den wert hinter b auslesen und verändern.
----
2te methode ist die sogenannte reclass variante.
hierbei wird die class nachgebaut in einem struct und dann auf den pointer initialisiert.
d.h.:
Code:
struct xxx {
float a; // 0x0
float b; // 0x4
} * p_xxx = (xxx*)THIS_PTR;
mit p_xxx->b kann dann auf das element b zugegriffen werden.
---
die zweite variante verursacht weniger lags und ist weitaus professioneller, denn sie erspart einem unnötiges type-casting.