Wat wordt er precies bedoeld met “de-refereren met een NULL-aanwijzer”?

Ik ben een complete beginner op het gebied van C, en tijdens mijn universitaire werk ben ik opmerkingen in code tegengekomen die vaak verwijzen naar het de-referentie van een NULL-aanwijzer. Ik heb wel een achtergrond in C#, ik heb begrepen dat dit lijkt op een “NullReferenceException” die je in .Net krijgt, maar nu heb ik ernstige twijfels.

Kan iemand me in lekentaal uitleggen wat dit precies is en waarom het slecht is?


Antwoord 1, autoriteit 100%

Een NULL-aanwijzer verwijst naar geheugen dat niet bestaat. Dit kan adres 0x00000000zijn of een andere door de implementatie gedefinieerde waarde (zolang het nooit een echt adres kan zijn). Dereferentie ervan betekent dat u probeert toegang te krijgen tot alles waarnaar wordt verwezen door de aanwijzer. De operator *is de operator voor dereferentie:

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

Dit is precies hetzelfde als een NullReferenceExceptionin C#, behalve dat pointers in C kunnen verwijzen naar elk gegevensobject, zelfs elementen in een array.


Antwoord 2, autoriteit 42%

Dereferentiebetekent gewoon het lezen van de geheugenwaarde op een bepaald adres. Dus als je een aanwijzer naar iets hebt, betekent derefereren van de aanwijzerhet lezen of schrijven van de gegevens waarnaar de aanwijzer verwijst.

In C, de Unary *Operator is de Deleferencing-operator. Als xeen aanwijzer is, dan is dan *xwat xpunten naar. De Unary &Operator is het -adres – van -exploitant. Als xiets is, is dan &xhet adres waarop xis opgeslagen in het geheugen. De *en &Operators zijn inversies van elkaar: als xgegevens zijn en yis Aanwijzer, dan zijn deze vergelijkingen altijd waar:

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

Een null-aanwijzer is een aanwijzer die niet wijst op eventuele geldige gegevens (maar het is niet de enige dergelijke pointer). De C-standaard zegt dat het undefined gedrag is om een ​​null-aanwijzer te derferen. Dit betekent dat absoluut alles kan gebeuren: het programma kan crashen, het kan stil blijven werken, of het kan je harde schijf wissen (hoewel dat nogal onwaarschijnlijk is).

In de meeste implementaties krijgt u een “segmentatiefout” of “toegangsschending” als u dit probeert te doen, wat bijna altijd zal resulteren in uw programma dat wordt beëindigd door het besturingssysteem. Hier is een manier waarop een null-aanwijzer kan worden afgespoord:

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

en Ja, Derferencing Een null-aanwijzer is vrijwel precies zoals een NullReferenceExceptionin C # (of een NullPointerExceptionin Java), behalve dat de Langauge-standaard een beetje meer is Nuttig hier. In C # heeft Deleferencing een null-referentie goed gedefinieerd gedrag: het gooit altijd een NullReferenceException. Er is geen manier waarop uw programma kan blijven werken of uw harde schijf als in C wissen (tenzij er een bug is in de taalruntime, maar opnieuw is dat ook ongelooflijk onwaarschijnlijk).


Antwoord 3, Autoriteit 3%

het betekent

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

In principe, bijna alles met (*p)of impliciet betrekken (*p), b.v. p->...DIE IS EEN SPOTHAND VOOR (*p). ...; behalve voor aanwijzing aanwijzer.


Antwoord 4, Autoriteit 2%

van wiki

Een nulpointer heeft een gereserveerde waarde, vaak maar niet noodzakelijk de waarde nul, wat aangeeft dat het verwijst naar geen object
..

Aangezien een null-gewaardeerde aanwijzer niet verwijst naar een zinvol voorwerp, veroorzaakt een poging om een ​​nul-aanwijzer te ontladen, meestal een runtime-fout.

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

Antwoord 5

Citaat uit wikipedia:

Een aanwijzer verwijst naar een locatie in
geheugen, en het verkrijgen van de waarde bij de
locatie waarnaar een aanwijzer verwijst, is bekend
als dereferentievan de aanwijzer.

Dereferentie wordt gedaan door de unary *-operator op de aanwijzer toe te passen.

int x = 5;
int * p;      // pointer declaration
p = &x;       // pointer assignment
*p = 7;       // pointer dereferencing, example 1
int y = *p;   // pointer dereferencing, example 2

“Dereferentie van een NULL-aanwijzer” betekent het uitvoeren van *pwanneer de pNULL

is


Antwoord 6

Een NULL-aanwijzer wijst naar geheugen dat niet bestaat, en zal Segmentatiefoutveroorzaken. Er is een eenvoudigere manier om de verwijzing naar een NULL-aanwijzer te verwijderen, kijk eens.

int main(int argc, char const *argv[])
{
    *(int *)0 = 0; // Segmentation fault (core dumped)
    return 0;
}

Aangezien 0nooit een geldige pointerwaarde is, treedt er een fout op.

SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=NULL}

Other episodes