NULL (C)

NULL i programmeringsspråken C och C++  är ett makro som deklareras i rubrikfilen stddef.h ( och andra huvudfiler). Värdet på detta makro är en implementeringsberoende nollpekarkonstant . 

En nollpekarkonstant är ett heltalskonstantuttryck med värdet 0 eller (endast i C) samma uttryck cast till typ void*. En nollpekarkonstant cast till valfri pekartyp är en nollpekare . Det är garanterat att en nollpekare inte är lika med en pekare till något objekt (i vidaste bemärkelsen, någon data) eller funktion. Det är garanterat att två nollpekare är lika. Att bortreferensera en nollpekare är en operation med odefinierat beteende .

Med andra ord tillhandahåller implementeringen ett speciellt värde - en nollpekarkonstant, som kan tilldelas vilken pekare som helst och en sådan pekare, när den jämförs, kommer inte att vara lika med någon "korrekt" pekare. Det vill säga, vi kan anta att en nollpekare inte innehåller en giltig adress i minnet.

Använder

Nollpekare är utformade som ett bekvämt sätt att "markera" pekare som inte är kända för att peka på en giltig minnesadress. Till exempel, när du deklarerar en pekare som en automatisk variabel, är dess värde odefinierat. För att notera att denna pekare ännu inte innehåller en giltig adress i minnet, tilldelas en sådan pekare en nollpekarkonstant:

void f ( void ) { int * x = NULL ; /* ... */ }

Det är en bra programmeringsstil att tilldela en nollpekare till en pekare efter att ha frigjort minnet den refererade till. Dessutom är användningen av nollningspekare relevant för säkerheten att frigöra minne: raderingsoperationen i C ++ ( fri i C) är säker för en nollpekare. Till exempel:

TYPE * foo = ny TYPE (); //använd foo ta bort foo ; // foo != NULL // någon programkod radera foo ; //FEL! minne är inte längre tillgängligt

medan det i den här versionen inte kommer att finnas något fel

TYPE * foo = ny TYPE (); //använd foo ta bort foo ; // foo != NULL foo = NULL ; // foo == NULL // någon programkod radera foo ; //inget fel: delete kontrollerar värdet på foo

Pekarmått

När en funktion anropas kan NULL skickas till ett av argumenten. Makrot NULL kan definieras på olika sätt i olika kompilatorer, inklusive

#define NULL 0

#define NULL ((void *)0)

I det första fallet är NULL av typen int, och i det andra fallet är det av typen void*. Det finns arkitekturer där sizeof(int) != sizeof(void*), sedan på olika plattformar kommer funktionen att få ett annat antal byte, vilket kan störa dess funktion. För närvarande görs ett försök att lösa detta problem i C genom att införa nullptr, se förslag N 2394 [1] .

Avlägsna nollpekare

Att bortreferensera en nollpekare är en operation med odefinierat beteende . Inga begränsningar införs för implementeringen : till exempel kan en åtkomst till minne som inte är avsedd att användas av detta program inträffa (det vill säga vid läsning kommer "skräp" att läsas, och när du skriver kommer värdet att skrivas till ett minnesområde som inte tillhör programmet). Till exempel, i DOS kommer att skriva till adressen noll skriva över åtminstone nollavbrottsvektorn , så nästa anrop till int 0 kommer med största sannolikhet att hänga systemet. Detta resulterar dock oftast i ett körtidsfel (om operativsystemet implementerar minnesskydd och åtkomst till icke-allokerat minne för processen blockeras). Till exempel, i Windows 9x , utfärdas meddelandet "Allmänt skyddsfel" - "Programmet utförde en olaglig operation och kommer att stängas" ( Engelska  allmänt skyddsfel, GPF ) oftast i de fall där programmet kommer åt minnet enligt felaktig ( inklusive oinitierad eller redan frigjord) pekare. På Unix-liknande operativsystem , i sådana situationer, tar processen emot en SIGSEGV- signal och dess hanterare skriver ut meddelandet " Segmenteringsfel ".

Nullpekare i C++

Om du tar en specifik implementering av NULL i källfiler kan den definieras som (void*)0 eller som 0. Att använda NULL i C++-projekt kan leda till fel. Till exempel

int ( ClassName ::* pf )() = NULL ;

kommer att resultera i ett kompileringsfel om NULL definieras som (void*)0 (till exempel inkluderades en rubrik indirekt där standard C++-definitionen av NULL överlappar). Därför rekommenderas det inte att använda NULL i formen ((void *)0) i C++-program. C ++ 11 -standarden lägger till ett nytt nyckelord nullptr [2] [3] för att beteckna en nollpekare .

Se även

Anteckningar

  1. N   2394 _ . Öppna standarder . Hämtad 22 maj 2020. Arkiverad från originalet 27 juli 2020.
  2. JTC1/SC22/WG21 - C++ Standards Committee. SC22/WG21/N2431 = J16/07-0301 "Ett namn på nollpekaren: nullptr"  (engelska) (PDF)  (länk ej tillgänglig) . JTC1.22.32 . C++ Standards Committee (2 oktober 2007). Datum för åtkomst: 4 oktober 2010. Arkiverad från originalet den 11 februari 2012.  (Engelsk)
  3. Scott Meyers , Sammanfattning av C++11-funktionstillgänglighet i gcc och MSVC Arkiverad 26 oktober 2011 på Wayback Machine , 16 augusti 2011

Länkar