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 0x00000000
zijn 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 NullReferenceException
in 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 x
een aanwijzer is, dan is dan *x
wat x
punten naar. De Unary &
Operator is het -adres – van -exploitant. Als x
iets is, is dan &x
het adres waarop x
is opgeslagen in het geheugen. De *
en &
Operators zijn inversies van elkaar: als x
gegevens zijn en y
is 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 NullReferenceException
in C # (of een NullPointerException
in 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 *p
wanneer de p
NULL
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}