NULL i programmeringssprogene C og C++ er en makro erklæret i stddef.h header-filen (og andre header-filer). Værdien af denne makro er en implementeringsafhængig nul pointer-konstant .
En nulpointerkonstant er et heltalskonstantudtryk med værdien 0 eller (kun i C) det samme udtryk, der er castet til type void*. En nul-pointer-konstant cast til enhver pointertype er en nul-pointer . Det er garanteret, at en nul-pointer ikke er lig med en pointer til noget objekt (i bredeste forstand, nogen data) eller funktion. Det er garanteret, at to nullpointere er ens. At derhenvise en nul-pointer er en operation med udefineret adfærd .
Med andre ord giver implementeringen en speciel værdi - en nul pointer-konstant, som kan tildeles enhver pointer, og en sådan pointer vil, når den sammenlignes, ikke være lig med nogen "korrekt" pointer. Det vil sige, at vi kan antage, at en null-pointer ikke indeholder en gyldig adresse i hukommelsen.
Nul-pegere er designet som en bekvem måde at "markere" pegere, som ikke vides at pege på en gyldig hukommelsesadresse. For eksempel, når en pointer erklæres som en automatisk variabel, er dens værdi udefineret. For at bemærke, at denne pointer endnu ikke indeholder en gyldig adresse i hukommelsen, er en sådan pointer tildelt en nul-pointerkonstant:
ugyldig f ( ugyldig ) { int * x = NULL ; /* ... */ }Det er en god programmeringsstil at tildele en nul-markør til en pointer efter at have frigjort den hukommelse, den refererede til. Derudover er brugen af nulstillingsmarkører relevant for sikkerheden ved at frigøre hukommelse: sletningsoperationen i C ++ ( fri i C) er sikker for en nulmarkør. For eksempel:
TYPE * foo = ny TYPE (); //brug foo slet foo ; // foo != NULL // noget programkode slet foo ; //FEJL! hukommelse er ikke længere tilgængeligmens der i denne version ikke vil være nogen fejl
TYPE * foo = ny TYPE (); //brug foo slet foo ; // foo != NULL foo = NULL ; // foo == NULL // noget programkode slet foo ; //ingen fejl: delete kontrollerer værdien af fooNår du kalder en funktion, kan NULL overføres til et af argumenterne. Makroen NULL kan defineres på forskellige måder i forskellige compilere, herunder
#define NULL 0
#define NULL ((void *)0)
I det første tilfælde er NULL af typen int, og i det andet tilfælde er det af typen void*. Der er arkitekturer, hvor sizeof(int) != sizeof(void*), så på forskellige platforme vil funktionen modtage et forskelligt antal bytes, hvilket kan forstyrre dens drift. Dette problem forsøges i øjeblikket at løse i C ved at indføre nullptr, se forslag N 2394 [1] .
At derhenvise en nul-pointer er en operation med udefineret adfærd . Der er ingen begrænsninger på implementeringen : for eksempel kan der opstå en adgang til hukommelse, der ikke er beregnet til brug af dette program (det vil sige, når du læser, vil "skrald" blive læst, og når du skriver, vil værdien blive skrevet til et hukommelsesområde, der ikke hører til programmet). For eksempel, i DOS, vil skrivning til adresse nul overskrive i det mindste nul -interrupt-vektoren , så det næste kald til int 0 vil højst sandsynligt hænge systemet. Dette resulterer dog oftest i en køretidsfejl (hvis operativsystemet implementerer hukommelsesbeskyttelse og adgang til ikke-allokeret hukommelse for processen er blokeret). For eksempel i Windows 9x udsendes meddelelsen "Generel beskyttelsesfejl" - "Programmet udførte en ulovlig handling og vil blive lukket" ( engelsk general protection fault, GPF ) udsendes oftest i tilfælde, hvor programmet får adgang til hukommelsen i henhold til forkert ( inklusive uinitialiseret eller allerede frigivet) pointer. På Unix-lignende operativsystemer modtager processen i sådanne situationer et SIGSEGV -signal, og dens behandler udskriver meddelelsen " Segmenteringsfejl ".
Hvis du tager en specifik implementering af NULL i kildefiler, så kan den defineres som (void*)0 eller som 0. Brug af NULL i C++ projekter kan føre til fejl. For eksempel
int ( Klassenavn ::* pf )() = NULL ;vil resultere i en kompileringsfejl, hvis NULL er defineret som (void*)0 (f.eks. blev en header indirekte inkluderet, hvor standard C++ definitionen af NULL overlapper). Derfor anbefales det ikke at bruge NULL i formen ((void *)0) i C++-programmer. C++11 - standarden tilføjer et nyt nøgleord nullptr [2] [3] for at angive en null-pointer .