c - strukturen - Was genau ist gemeint, wenn man einen NULL-Zeiger referenziert?




zeiger strukturen c (4)

Aus dem wiki

Ein Nullzeiger hat einen reservierten Wert, oft, aber nicht notwendigerweise, den Wert Null, was anzeigt, dass er sich auf kein Objekt bezieht
..

Da sich ein nullwertiger Zeiger nicht auf ein sinnvolles Objekt bezieht, verursacht ein Versuch, einen Nullzeiger zu dereferenzieren, normalerweise einen Laufzeitfehler.

int val =1;
int *p = NULL;
*p = val; // Whooosh!!!! 

Ich bin ein absoluter Neuling für C, und während meiner Universitätsarbeit bin ich auf Kommentare im Code gestoßen, die sich oft auf das Aufheben der Referenzierung eines NULL-Zeigers beziehen. Ich habe einen Hintergrund in C #, ich bin davon ausgegangen, dass dies ähnlich wie eine "NullReferenceException", die Sie in .Net bekommen, aber jetzt habe ich ernsthafte Zweifel.

Kann mir bitte jemand in Laiensprache genau erklären, was das ist und warum es schlecht ist?


Es bedeutet

myclass *p = NULL;
*p = ...;  // illegal: dereferencing NULL pointer
... = *p;  // illegal: dereferencing NULL pointer
p->meth(); // illegal: equivalent to (*p).meth(), which is dereferencing NULL pointer

myclass *p = /* some legal, non-NULL pointer */;
*p = ...;  // Ok
... = *p;  // Ok
p->meth(); // Ok, if myclass::meth() exists

im Grunde fast alles was (*p) oder implizit (*p) , zB p->... was eine Abkürzung für (*p). ... (*p). ... ; außer Zeigerdeklaration.


Dereferenzierung bedeutet nur das Lesen des Speicherwerts an einer bestimmten Adresse. Wenn Sie also einen Zeiger auf etwas haben, bedeutet das Dereferenzieren des Zeigers , die Daten zu lesen oder zu schreiben, auf die der Zeiger zeigt.

In C ist der unäre * Operator der Dereferenzierungsoperator. Wenn x ein Zeiger ist, dann ist *x worauf x zeigt. Der unäre Operator ist der Adressenoperator . Wenn x irgendetwas ist, dann ist &x die Adresse, an der x im Speicher gespeichert ist. Die Operatoren * und & sind Inversen voneinander: Wenn x irgendwelche Daten und y irgendein Zeiger ist, dann sind diese Gleichungen immer wahr:

*(&x) == x
&(*y) == y

Ein Nullzeiger ist ein Zeiger, der nicht auf gültige Daten zeigt (aber nicht der einzige derartige Zeiger). Der C-Standard besagt, dass es ein undefiniertes Verhalten ist , einen Nullzeiger zu dereferenzieren. Das bedeutet, dass absolut alles passieren kann: Das Programm könnte abstürzen, es könnte weiter leise arbeiten, oder es könnte Ihre Festplatte löschen (obwohl das eher unwahrscheinlich ist).

In den meisten Implementierungen erhalten Sie einen "Segmentierungsfehler" oder "Zugriffsverletzung", wenn Sie dies versuchen, was fast immer dazu führt, dass Ihr Programm vom Betriebssystem beendet wird. Hier ist eine Möglichkeit, wie ein Nullzeiger dereferenziert werden könnte:

int *x = NULL;  // x is a null pointer
int y = *x;     // CRASH: dereference x, trying to read it
*x = 0;         // CRASH: dereference x, trying to write it

Und ja, Dereferenzierung eines Null-Zeigers ist ziemlich genau wie eine NullReferenceException in C # (oder eine NullPointerException in Java), außer dass der Sprachstandard hier ein wenig hilfreicher ist. In C # hat die Dereferenzierung einer NullReferenceException ein wohldefiniertes Verhalten: Sie NullReferenceException immer eine NullReferenceException . Es gibt keine Möglichkeit, dass Ihr Programm ruhig weiterarbeiten oder Ihre Festplatte wie in C löschen kann (es sei denn, es gibt einen Fehler in der Sprachlaufzeit, aber auch das ist unglaublich unwahrscheinlich).


Ein NULL Zeiger verweist auf Speicher, der nicht vorhanden ist. Dies kann die Adresse 0x00000000 oder ein anderer implementierungsdefinierter Wert sein (solange es keine echte Adresse sein kann). Dereferenzieren heißt, versuchen, auf alles zuzugreifen, auf das der Zeiger zeigt. Der Operator * ist der Dereferenzierungsoperator:

int a, b, c; // some integers
int *pi;     // a pointer to an integer

a = 5;
pi = &a; // pi points to a
b = *pi; // b is now 5
pi = NULL;
c = *pi; // this is a NULL pointer dereference

Dies ist genau dasselbe wie eine NullReferenceException in C #, außer dass Zeiger in C auf jedes Datenobjekt zeigen können, auch auf Elemente innerhalb eines Arrays.





pointers