Wenn ich Speicheradressen subtrahiere, warum ist das Ergebnis kleiner als erwartet?

8

Ich habe folgendes Programm:

%Vor%

Ich kann X 's Layout im Speicher visualisieren, 10 Kästchen mit int und float , p1 zeigen auf den Anfang der zweiten Box ( x[1] ) und p2 zeigen am Anfang der 6. Box ( x[5] ):

%Vor%

Ist meine Zeichnung korrekt? Wenn ja, warum ist das Ergebnis von i 4? Haben Sie Schwierigkeiten, die Subtraktion zweier Adressen zu verstehen?

    
Kobe 02.12.2011, 13:37
quelle

1 Antwort

23

Dies ist, wie Zeigerarithmetik funktioniert. Überlegen Sie:

%Vor%

Zu diesem Zeitpunkt hat p2 nicht den Wert 101 , sondern 100 + sizeof(x) (also 8, also 108). Es wurde nicht um eins erhöht, sondern um ein Vielfaches von sizeof(x) ! Umgekehrt subtrahiert das Subtrahieren einer Ganzzahl von einem Zeiger Vielfache von sizeof(the pointed to type) .

Also, wenn du int diff = p2 - p1 machst, würdest du sicherlich erwarten, dass 1 zurück, nicht 8 ! Andernfalls würde das Subtrahieren der soeben hinzugefügten Zahl nicht den ursprünglichen Wert ergeben. Daher ergibt das Subtrahieren eines Zeigers von einem anderen nicht den Unterschied in den Speicheradressen, sondern die Anzahl der Elemente zwischen den zwei Zeigern.

Außerdem schreibt der Standard vor, dass die Pointer-Subtraktion bedeutungslos ist, wenn die beiden Zeiger nicht auf Elemente im selben Array zeigen (genauer gesagt, es ist undefiniertes Verhalten und Sie dürfen auch einen Zeiger auf "eins" verwenden) hinter dem letzten Element "auch wenn dort kein solches Objekt ist."

Zum Schluss, was ist, wenn der Compiler die Größe des angegebenen Typs nicht kennt (d. h. die Zeiger sind void* )? In diesem Fall ist Zeigerarithmetik überhaupt nicht erlaubt. Zum Beispiel:

%Vor%

¹ Einige Compiler können Zeigerarithmetik auf void* als Erweiterung zur Sprachspezifikation. In diesem Fall kann diese Anweisung tatsächlich kompiliert werden und das Ergebnis würde von der Spezifikation der Erweiterung abhängen (z. B. würde gcc mit dem Wert 101 enden).

    
Jon 02.12.2011, 13:41
quelle

Tags und Links