Ich kann nicht eine gute doppelte Antwort finden, also hier ist was los:
Pointer-Arithmetik geschieht immer in Einheiten der Basistyp des Zeigers. Das heißt, wenn Sie T *ptr
(ein Zeiger auf einen Typ T
) haben, dann ist ptr + 1
nicht das nächste Byte im Speicher, sondern das nächste T
.
Mit anderen Worten: Sie einen Zeiger wie eine Kombination aus einem Array vorstellen können und ein Index:
T *ptr;
T array[/*some size*/];
ptr = &array[n];
Wenn ptr
ist ein Zeiger auf array[n]
(das n-te Element), dann ist ptr + i
ein Zeiger auf array[n + i]
(das (n + i) -te Element).
Lassen Sie uns einen Blick auf den Code nehmen:
*((int*)basepointer+32) = 455;
Hier sind Sie basepointer
zu (int*)
Gießen, dann 32
ihm hinzufügen. Dies gibt Ihnen die Adresse des 32. int
nach basepointer
. Wenn Ihre Plattform 4-Byte-Ints verwendet, ist der tatsächliche Offset 32 * 4 = 128
Bytes. Hier speichern wir 455
.
Dann tun Sie
void *p = basepointer + 32;
Dies ist technisch ungültigen Code, weil basepointer
ein void *
ist, und Sie können Arithmetik in Bezug auf void
nicht tun, weil void
keine Größe hat. Als Erweiterung unterstützt gcc dies und gibt vor, void
hat die Größe 1
. (Aber Sie sollten wirklich nicht verlassen: cast unsigned char *
wenn Sie wollen byteweise Adressierung.)
Jetzt p
ist bei Offset 32
nach basepointer
.
a = *((int*)basepointer+32);
Wiederholt die Zeigerarithmetik von oben und ruft den Wert aus int
32 versetzt (d.h. Byte 128
Offset), die 455
noch ist.
b = *((int*)p);
Dies ruft der int
Wert bei Offset-Byte gespeichert 32
(die int
Offset 8
in diesem Beispiel entsprechen würde). Wir haben nie etwas hier gespeichert, so b
ist im Wesentlichen Müll (es ist zufällig 0
auf Ihrer Plattform).
Die kleinste Änderung dieses Code zu machen, wie wahrscheinlich zu erwarten ist
void *p = (int *)basepointer + 32; // use int-wise arithmetic to compute p
Versuchen Sie '* (int *) (Basiszeiger + 32) = 455;' in Ihrer zweiten Zeile stattdessen. Dann gehen Sie und lesen Sie über Zeigerarithmetik. – aragaer
@aragaer Keine gute Idee, wenn 'basepointer' den Typ' void * 'hat. – aschepler
Was ist die Art von Basispointer? – Bathsheba