Geschichte der Frage: In C sind Zeiger Variablen, die Adressen anderer Objekte speichern. Es stellt sich das Problem, wie man solche Werte vergleicht, da der Speicher auf die unvorhersehbarste Weise verteilt sein kann. Die Sprache erlaubt den Vergleich von Zeigern, legt aber eine Reihe von Einschränkungen fest, damit das Verhalten vorhersagbar bleibt.
Problem: Korrekt vergleichen kann man nur Zeiger auf Elemente desselben Arrays oder auf dasselbe Objekt. Der Vergleich von Zeigern, die auf nicht verbundene Objekte (verschiedene Variablen oder zugewiesene Speicherbereiche, die nicht zu einem gemeinsamen Array gehören) zeigen, ist ein undefiniertes Verhalten (undefined behavior).
Lösung: Man sollte den Vergleich von Zeigern zwischen nicht verbundenen Speicherbereichen vermeiden, ihn nur innerhalb eines Arrays/String/Puffers verwenden, und der Vergleich mit NULL ist sicher.
Beispielcode:
#include <stdio.h> int main() { int arr[5] = {1, 2, 3, 4, 5}; int *p1 = &arr[1]; int *p2 = &arr[3]; if (p1 < p2) { printf("p1 zeigt auf ein früheres Element des Arrays als p2\n"); } }
Wesentliche Merkmale:
1. Kann man Zeiger vergleichen, die über malloc erhalten wurden und auf verschiedene Speicherblöcke zeigen?
Nein, solche Zeiger dürfen nicht verglichen werden — das Verhalten ist nicht durch den Standard definiert. Es ist nur erlaubt, Zeiger auf denselben zugewiesenen Speicherblock oder mit NULL zu vergleichen.
2. Was gibt der Vergleich von Zeigern vom Typ int und double zurück, wenn sie auf verschiedene Variablen zeigen, aber denselben numerischen Wert haben?**
Ein Vergleich ist nur möglich, wenn beide Zeiger in denselben Typ konvertiert werden und auf dasselbe Objekt zeigen. Wenn dies nicht der Fall ist, ist das Ergebnis undefiniert — die Adresswerte können gleich sein, jedoch garantiert der Standard dieses Verhalten nicht.
3. Ist es korrekt, einen Zeiger auf das erste Element eines Arrays mit einem Zeiger auf das Ende zu vergleichen (z.B. arr und arr + N)?
Ja, das ist korrekt. arr + N zeigt auf das imaginäre Element, das nach dem letzten kommt, und der Compiler garantiert, dass arr <= arr + N.
Ein Mitarbeiter beschloss, eine Funktion zum Vergleich von Adressen zu implementieren, um zu bestimmen, "wurde zuerst erstellt" soll zwei Strukturen, die aus verschiedenen Speicherbereichen zugewiesen wurden, vergleichen.
Vorteile:
Nachteile:
Nach der Überprüfung wurde eine Kontrolle der Zugehörigkeit der Zeiger zu einem Speicherblock implementiert, indem alle Strukturen in einem gemeinsamen Puffer zugewiesen wurden und anschließend in zulässigen Grenzen verglichen wurde.
Vorteile:
Nachteile: