9.7 – Null-pekere – Lær C++ (2023)

I forrige leksjon (9.6 – Introduksjon til pekere), dekket vi det grunnleggende om pekere, som er objekter som har adressen til et annet objekt. Denne adressen kan derefereres ved hjelp av dereferenceoperatoren (*) for å få verdien på den adressen:

#include int main(){ int x{ 5 }; std::cout << x << '\n'; // skriv ut verdien av variabel x int* ptr{ &x }; // ptr inneholder adressen til x std::cout << *ptr << '\n'; // bruk dereference operator for å skrive ut verdien på adressen som ptr har (som er xs adresse) return 0;}

Eksempelet ovenfor skriver ut:

55

I forrige leksjon la vi også merke til at pekere ikke trenger å peke på noe. I denne leksjonen skal vi utforske slike tips (og de ulike implikasjonene av å peke på ingenting) videre.

Null-pekere

Foruten en minneadresse, er det én ekstra verdi som en peker kan inneholde: en nullverdi. ENnull verdi(ofte forkortet tilnull) er en spesiell verdi som betyr at noe ikke har noen verdi. Når en peker holder en nullverdi, betyr det at pekeren ikke peker på noe. En slik peker kalles anull-peker.

Den enkleste måten å lage en null-peker på er å bruke verdiinitialisering:

int main(){ int* ptr {}; // ptr er nå en null-peker, og inneholder ikke en adresseretur 0;}

Beste praksis

Verdi initialiser pekerne dine (for å være null-pekere) hvis du ikke initialiserer dem med adressen til et gyldig objekt.

Fordi vi kan bruke tilordning for å endre hva en peker peker på, kan en peker som opprinnelig er satt til null senere endres til å peke på et gyldig objekt:

#include int main(){ int* ptr {}; // ptr er en null-peker, og inneholder ikke en adresse int x { 5 }; ptr = &x; // ptr peker nå på objekt x (ikke lenger en null-peker) std::cout << *ptr << '\n'; // utskriftsverdi av x gjennom dereferert ptr return 0;}

Nullptr-nøkkelordet

Omtrent som nøkkelordeneekteogfalskrepresenterer boolske bokstavelige verdier, dennullptrnøkkelord representerer en null-peker bokstavelig. Vi kan brukenullptrå eksplisitt initialisere eller tilordne en peker en nullverdi.

int main(){ int* ptr { nullptr }; // kan bruke nullptr for å initialisere en peker til å være en null-peker int-verdi { 5 }; int* ptr2 { &verdi }; // ptr2 er en gyldig peker ptr2 = nullptr; // Kan tilordne nullptr for å gjøre pekeren til en null-peker someFunction(nullptr); // vi kan også sende nullptr til en funksjon som har en pekerparameter return 0;}

I eksemplet ovenfor bruker vi oppgave til å angi verdien avptr2tilnullptr, lagerptr2en null-peker.

Beste praksis

Bruknullptrnår du trenger en null-peker bokstavelig for initialisering, tilordning eller overføring av en null-peker til en funksjon.

Frareferanse til en null-peker resulterer i udefinert atferd

På samme måte som å avvise en dinglende (eller vill) peker fører til udefinert oppførsel, fører fravisning av en nullpeker også til udefinert oppførsel. I de fleste tilfeller vil det krasje applikasjonen din.

Følgende program illustrerer dette, og vil sannsynligvis krasje eller avslutte programmet unormalt når du kjører det (fortsett, prøv det, du vil ikke skade maskinen din):

#include int main(){ int* ptr {}; // Lag en null-peker std::cout << *ptr << '\n'; // Refererer null-pekeren returnerer 0;}

Konseptuelt gir dette mening. Å frareferanse til en peker betyr "gå til adressen pekeren peker på og få tilgang til verdien der". En null-peker har en null-verdi, som semantisk betyr at pekeren ikke peker på noe. Så hvilken verdi vil den få tilgang til?

Å tilfeldigvis avvise null- og dinglende pekere er en av de vanligste feilene C++-programmerere gjør, og er sannsynligvis den vanligste årsaken til at C++-programmer krasjer i praksis.

Advarsel

Når du bruker pekere, må du være ekstra forsiktig med at koden din ikke refererer til null eller hengende pekere, da dette vil forårsake udefinert oppførsel (sannsynligvis et programkrasj).

Ser etter null-pekere

Omtrent som vi kan bruke en betinget for å teste boolske verdier forekteellerfalsk, kan vi bruke en betinget for å teste om en peker har verdinullptreller ikke:

#include int main(){ int x { 5 }; int* ptr { &x }; // pekere konverteres til boolsk falsk hvis de er null, og boolsk sann hvis de ikke er null if (ptr == nullptr) // eksplisitt test for ekvivalens std::cout << "ptr er null\n"; else std::cout << "ptr er ikke-null\n"; int* nullPtr {}; std::cout << "nullPtr er " << (nullPtr==nullptr ? "null\n" : "ikke-null\n"); // eksplisitt test for ekvivalens return 0;}

Programmet ovenfor skriver ut:

ptr er ikke-nullnullPtr er null

I leksjonen4.9 -- Boolske verdier, la vi merke til at integralverdier implisitt vil konvertere til boolske verdier: en integralverdi på0konverterer til boolsk verdifalsk, og enhver annen integralverdi konverteres til boolsk verdiekte.

På samme måte vil pekere også implisitt konvertere til boolske verdier: en null-peker konverterer til boolsk verdifalsk, og en ikke-null-peker konverterer til boolsk verdiekte. Dette lar oss hoppe over eksplisitt testing fornullptrog bare bruk den implisitte konverteringen til boolsk for å teste om en peker er en null-peker. Følgende program tilsvarer det forrige:

#include int main(){ int x { 5 }; int* ptr { &x }; // pekere konverterer til boolsk usann hvis de er null, og boolsk sann hvis de ikke er null hvis (ptr) // implisitt konvertering til boolsk std::cout << "ptr er ikke-null\n"; else std::cout << "ptr er null\n"; int* nullPtr {}; std::cout << "nullPtr er " << (nullPtr ? "non-null\n" : "null\n"); // implisitt konvertering til boolsk avkastning 0;}

Advarsel

Betingelser kan bare brukes til å skille null-pekere fra ikke-null-pekere. Det er ingen praktisk måte å finne ut om en ikke-null-peker peker på et gyldig objekt eller dingler (peker på et ugyldig objekt).

Bruk nullptr for å unngå hengende pekere

Ovenfor nevnte vi at det å referere en peker som enten er null eller dingler, vil resultere i udefinert oppførsel. Derfor må vi sørge for at koden vår ikke gjør noen av disse tingene.

Vi kan enkelt unngå å dereferere en null-peker ved å bruke en betinget for å sikre at en peker ikke er null før vi prøver å dereferere den:

// Anta at ptr er en peker som kanskje er en null pointerif (ptr) // hvis ptr ikke er en null pointer std::cout << *ptr << '\n'; // okay to dereferenceelse // gjør noe annet som ikke involverer dereferencing ptr (skriv ut en feilmelding, ikke gjør noe i det hele tatt, osv...)

Men hva med dinglende pekere? Fordi det ikke er noen måte å oppdage om en peker dingler, må vi unngå å ha noen hengende pekere i programmet vårt i utgangspunktet. Vi gjør det ved å sikre at enhver peker som ikke peker på et gyldig objekt er satt tilnullptr.

På den måten, før vi refererer en peker, trenger vi bare å teste om den er null - hvis den ikke er null, antar vi at pekeren ikke dingler.

Beste praksis

En peker skal enten inneholde adressen til et gyldig objekt, eller settes til nullptr. På den måten trenger vi bare å teste pekere for null, og kan anta at enhver ikke-null-peker er gyldig.

Dessverre er det ikke alltid lett å unngå hengende pekere: når en gjenstand blir ødelagt, vil alle pekere til den gjenstanden bli hengende. Slike pekere erikkenullstilles automatisk! Det er programmererens ansvar å sørge for at alle pekere til et objekt som nettopp har blitt ødelagt er riktig satt tilnullptr.

Advarsel

Når et objekt blir ødelagt, vil eventuelle pekere til det ødelagte objektet bli hengende (de vil ikke automatisk settes tilnullptr). Det er ditt ansvar å oppdage disse tilfellene og sørge for at disse pekerne blir satt tilnullptr.

Eldre null-peker bokstaver: 0 og NULL

I eldre kode kan du se to andre bokstavelige verdier brukt i stedet fornullptr.

Den første er den bokstavelige0. I sammenheng med en peker, det bokstavelige0er spesielt definert til å bety en nullverdi, og er den eneste gangen du kan tilordne en integral literal til en peker.

int main(){ float* ptr { 0 }; // ptr er nå en null-peker (for eksempel bare, ikke gjør dette) float* ptr2; // ptr2 er uinitialisert ptr2 = 0; // ptr2 er nå en null-peker (kun for eksempel, ikke gjør dette) return 0;}

Som en side...

På moderne arkitekturer, adressen0brukes vanligvis til å representere en null-peker. Denne verdien er imidlertid ikke garantert av C++-standarden, og noen arkitekturer bruker andre verdier. Det bokstavelige0, når den brukes i sammenheng med en null-peker, vil bli oversatt til hvilken adresse arkitekturen bruker for å representere en null-peker.

I tillegg er det en forprosessormakro kaltNULL(definert i -overskriften). Denne makroen er arvet fra C, hvor den vanligvis brukes til å indikere en null-peker.

#include  // for NULLint main(){ double* ptr { NULL }; // ptr er en nullpeker dobbel* ptr2; // ptr2 er uinitialisert ptr2 = NULL; // ptr2 er nå en null-peker}

Både0ogNULLbør unngås i moderne C++ (bruknullptri stedet). Vi diskuterer hvorfor i leksjonen9.10 -- Pass ved adresse (del 2).

Foretrekk referanser fremfor pekere når det er mulig

Pekere og referanser gir oss begge muligheten til å få tilgang til andre objekter indirekte.

Pekere har tilleggsevnen til å kunne endre det de peker på, og å bli pekt på null. Disse pekeregenskapene er imidlertid også iboende farlige: En null-peker risikerer å bli referert til, og muligheten til å endre hva en peker peker på kan gjøre det lettere å lage hengende pekere:

int main(){ int* ptr { }; { int x{ 5 }; ptr = &x; // sett pekeren til et objekt som vil bli ødelagt (ikke mulig med en referanse) } // ptr dingler nå retur 0;}

Siden referanser ikke kan bindes til null, trenger vi ikke å bekymre oss for nullreferanser. Og fordi referanser må være bundet til et gyldig objekt ved opprettelse og deretter ikke kan settes tilbake, er dinglende referanser vanskeligere å lage.

Fordi de er sikrere, bør referanser foretrekkes fremfor pekere, med mindre tilleggsfunksjonene gitt av pekere er nødvendig.

Beste praksis

Foretrekk referanser fremfor pekere med mindre tilleggsfunksjonene som pekere er nødvendige.

Quiz-tid

Spørsmål 1

1a) Kan vi avgjøre om en peker er en null-peker eller ikke? Hvis ja, hvordan?

Vis løsning

1b) Kan vi avgjøre om en ikke-null-peker er gyldig eller dingler? Hvis ja, hvordan?

Vis løsning

Spørsmål #2

For hvert underpunkt, svar "ja", "nei" eller "muligens" på om handlingen som beskrives vil resultere i udefinert atferd (umiddelbart). Hvis svaret er "mulig", avklar når.

2a) Tilordne en ny adresse til en peker

Vis løsning

2b) Tilordne nullptr til en peker

Vis løsning

2c) Frareferanse til en peker til et gyldig objekt

Vis løsning

2d) Å henvise til en dinglende peker

Vis løsning

2e) Frareferanse til en null-peker

Vis løsning

2f) Frareferanse til en ikke-null-peker

Vis løsning

Spørsmål #3

Hvorfor skal vi sette pekere som ikke peker til et gyldig objekt til "nullptr"?

Vis løsning

Neste leksjon9.8Pekere og konstTilbake til innholdsfortegnelsenForrige leksjon9.6Introduksjon til pekere

FAQs

What does nullptr do in C++? ›

The nullptr keyword represents a null pointer value. Use a null pointer value to indicate that an object handle, interior pointer, or native pointer type does not point to an object.

What is null check in C++? ›

In C or C++, there is no special method for comparing NULL values. We can use if statements to check whether a variable is null or not.

Does nullptr == null C++? ›

nullptr is a new keyword introduced in C++11. nullptr is meant as a replacement to NULL . nullptr provides a typesafe pointer value representing an empty (null) pointer. The general rule of thumb that I recommend is that you should start using nullptr whenever you would have used NULL in the past.

What is the null pointer in C++11? ›

In C++11, nullptr is a new keyword that can (and should!) be used to represent NULL pointers; in other words, wherever you were writing NULL before, you should use nullptr instead.

What happens if you delete nullptr C++? ›

Deleting a null pointer has no effect. It's not good coding style necessarily because it's not needed, but it's not bad either. If you are searching for good coding practices consider using smart pointers instead so then you don't need to delete at all.

What type is a nullptr in C++? ›

std::nullptr_t is the type of the null pointer literal, nullptr. It is a distinct type that is not itself a pointer type or a pointer to member type. Its values are null pointer constants (see NULL), and may be implicitly converted to any pointer and pointer to member type.

What is an example of a null statement in C++? ›

for ( i = 0; i < 10; line[i++] = 0 ) ; In this example, the loop expression of the for statement line[i++] = 0 initializes the first 10 elements of line to 0. The statement body is a null statement, since no further statements are necessary.

How do you check if a value is a nullptr? ›

To test if a pointer is a nullptr , you can compare it by using the = and the != operator. This is useful when we are using pointers to access objects. Since it is not possible to access data through a null pointer, a check ptr == nullptr or ptr !=

How to do null check for a string? ›

You can use the IsNullOrWhiteSpace method to test whether a string is null , its value is String. Empty, or it consists only of white-space characters.

Is nullptr the same as 0? ›

nullptr vs NULL

NULL is 0(zero) i.e. integer constant zero with C-style typecast to void*, while nullptr is prvalue of type nullptr_t which is integer literal evaluates to zero.

What is the difference between {} and nullptr? ›

nullptr is an object that can be converted to a value of any pointer type. nullopt is an object that can be converted to a value of any optional type. {} is (in a context expecting a value) an expression that means "a default constructed object of type T ", where T is some type inferred from the context.

Can you point to a nullptr? ›

A pointer cannot point to null; it can be null (a null pointer, NULL ), which, as you say, means it doesn't point to anything.

How to show null characters in C? ›

The C and C++ languages have a null character (NUL), a null pointer (NULL), and a null statement (just a semicolon (;)). The C NUL is a single character that compares equal to 0. The C NULL is a special reserved pointer value that does not point to any valid data object.

How to set null value in C? ›

In C programming language a Null pointer is a pointer which is a variable with the value assigned as zero or having an address pointing to nothing. So we use keyword NULL to assign a variable to be a null pointer in C it is predefined macro.

Is A void pointer null? ›

The difference between Null pointer and Void pointer is that Null pointer is a value and Void pointer is a type.

Do I need to initialize pointer as nullptr? ›

Why would you initialize a pointer to nullptr if you could just declare it and then initialize it later? Yes. The important thing to remember is that as soon as you allocate memory to the pointer you have to manage it. So nullptr is a sentinel value that means the pointer doesn't point to anything.

Is nullptr true or false C++? ›

A null pointer with the nullptr value is converted to false .

Do pointers initialize to nullptr? ›

A pointer can also be initialized to null using any integer constant expression that evaluates to 0, for example char *a=0; . Such a pointer is a null pointer. It does not point to any object.

What is the difference between delete pointer and nullptr in C++? ›

deleting the pointer frees the memory that the pointer points to. Just setting the pointer to nullptr will cause a memeory leak as there is no way to now delete the memory the pointer was pointing to.

What is null and void in C++? ›

void* is just a pointer to an undefined type. A void* can be set to any memory location. A NULL pointer is a any pointer which is set to NULL (0). So yes, they are different, because a void pointer is a datatype, and a NULL pointer refers to any pointer which is set to NULL.

Where is null declared in C++? ›

h . The C++ standard requires that NULL be defined in the c* header corresponding to each of those. The C standard is very strict about the names a standard can define--each standard header must define precisely the names the standard requires that header to define.

Can you set a variable to null in C++? ›

While it is true that an object cannot be "empty/null" in C++, in C++17, we got std::optional to express that intent. A plain int (or any type), however, can never be "null" or "empty" in any useful sense.

How do you check if a value is a nullptr in C++? ›

Checking if a pointer variable is null in C++ can be done using an `if` statement. In this example, we assign the value of `nullptr` to our pointer variable and then use the `if` statement to check if it's equal to that same value.

How do you check for null? ›

How to Check for Null in JavaScript with Equality Operators. The equality operators provide the best way to check for null . You can either use the loose/double equality operator ( == ) or the strict/triple equality operator ( === ).

What is the difference between null and nullptr and 0? ›

The difference between the nullptr keyword and NULL macro (along with a zero literal) is that NULL , along with zero literal ( 0 ), don't preserve the meaning of the null pointer constant unless they're no longer a literal.

Can we pass null to string? ›

It is a special value that we can assign to any reference type variable. We can cast null into any type in which we want, such as string, int, double, etc.

How do you check if string is empty null or undefined? ›

The Solution. The isEmpty function uses the equality operator ( == ) to check if the argument value is null or undefined . This works because if one of the operands is null or undefined , the other operand must be null or undefined for the equality comparison to return true .

Does isBlank check null? ›

isBlank(< string >)​

Checks if the value is null, empty, or contains only whitespace characters. Returns true if the string is null, empty, or only whitespace.

Why are null pointers a mistake? ›

Because a null pointer does not point to a meaningful object, an attempt to dereference (i.e., access the data stored at that memory location) a null pointer usually (but not always) causes a run-time error or immediate program crash.

Why is nullptr better than null? ›

nullptr is a keyword that represents zero as an address (its type is considered a pointer-type), while NULL is the value zero as an int . If you're writing something where you're referring to the zero address, rather than the value zero, you should use nullptr .

How do you declare a null character? ›

On some keyboards, one can enter a null character by holding down Ctrl and pressing @ (on US layouts just Ctrl + 2 will often work, there being no need for ⇧ Shift to get the @ sign).

Is C++ string null terminated? ›

Actually, as of C++11 std::string is guaranteed to be null terminated. Specifically, s[s. size()] will always be '\0' .

Is null always 0 in C? ›

The null pointer constant is always 0. The NULL macro may be defined by the implementation as a naked 0 , or a cast expression like (void *) 0 , or some other zero-valued integer expression (hence the "implementation defined" language in the standard).

How do you insert a null value? ›

NULL can be inserted in any column by using the assignment operator "=". Also, to test whether a NULL is present or not we have to use certain operators, for example, IS NULL and IS NOT NULL. NULL value in SQL signifies that the column's corresponding value is either undefined or unknown.

Can I set a value to null? ›

You can use this query, to set the specific row on a specific column to null this way: Update myTable set MyColumn = NULL where Field = Condition. Here, the above code will set the specific cell to null as per the inner question (i.e. To clear the value from a cell and make it NULL).

What is the size of null in C? ›

The string is terminated by a null character. Array elements after the null character are not part of the string, and their contents are irrelevant. The length of a null string is 0.

Is null the same as void? ›

The difference between null and void as term for nothing stems from their place in physical space. A void is nothing but takes up space; null is nothing at all. In other words, you could measure a void but null offers nothing to measure.

Is null a character pointer? ›

In C programming language, a variable that can point to or store the address of another variable is known as pointer. And a null pointer is a pointer which points at nothing.

What is the example of null pointer? ›

A null pointer constant is an integer constant expression that evaluates to zero. For example, a null pointer constant can be 0, 0L , or such an expression that can be cast to type (void *)0 .

Is it better to use null or nullptr? ›

Avoid using NULL or zero ( 0 ) as a null pointer constant; nullptr is less vulnerable to misuse and works better in most situations. For example, given func(std::pair<const char *, double>) , then calling func(std::make_pair(NULL, 3.14)) causes a compiler error.

What is null vs nullptr vs 0 C++? ›

nullptr is a keyword that denotes the pointer literal with the unique std::nullptr_t type. The difference between the nullptr keyword and NULL macro (along with a zero literal) is that NULL , along with zero literal ( 0 ), don't preserve the meaning of the null pointer constant unless they're no longer a literal.

What is the difference between delete and set to nullptr in C++? ›

deleting the pointer frees the memory that the pointer points to. Just setting the pointer to nullptr will cause a memeory leak as there is no way to now delete the memory the pointer was pointing to.

Why should null values be avoided? ›

They should be avoided to avoid the complexity in select & update queries and also because columns which have constraints like primary or foreign key constraints cannot contain a NULL value.

Is nullptr guaranteed to be zero? ›

Is NULL guaranteed to be 0? According to the standard, NULL is a null pointer constant (i.e. literal). Exactly which one, is implementation defined. Prior to C++11, null pointer constants were integral constants whose integral value is equal to 0, so 0 or 0l etc.

Is null the same as false in C++? ›

NULL is used to denote the null pointer constant, which evaluates to false in a boolean context.

Is empty string same as null in C++? ›

The value null represents the absence of any object, while the empty string is an object of type String with zero characters. If you try to compare the two, they are not the same.

Is null better than undefined? ›

Null in JavaScript means an empty value and is also a primitive type in JavaScript. The variable which has been assigned as null contains no value. Undefined, on the other hand, means the variable has been declared, but its value has not been assigned.

How do I check if a string is nullptr? ›

You can use the IsNullOrWhiteSpace method to test whether a string is null , its value is String. Empty, or it consists only of white-space characters.

How to check if a pointer is nullptr in C++? ›

To test if a pointer is a nullptr , you can compare it by using the = and the != operator. This is useful when we are using pointers to access objects. Since it is not possible to access data through a null pointer, a check ptr == nullptr or ptr !=

What value does a nullptr have? ›

You can use an integer constant expression with the value 0 or an expression that is cast to (void *)0 as a null pointer constant. The macro NULL and value 0 are equivalent as null pointer constants, but NULL is cleaner because it represents the purpose of using the constant for a pointer.

Does a nullptr occupy memory? ›

The null pointer does not allocate any extra memory to store anything on the heap (since there is nothing to store). However, your dictionary has to store the null pointer itself, which takes just as much space as any other pointer.

Is it OK to delete a nullptr? ›

C++ Junkie

Simple answer is YES. It is perfectly safe to delete a null pointer. In C++ delete operator is used to deallocate the memory block pointed by the pointer by releasing the memory allocated via new operator.

References

Top Articles
Latest Posts
Article information

Author: Merrill Bechtelar CPA

Last Updated: 10/21/2023

Views: 5365

Rating: 5 / 5 (70 voted)

Reviews: 85% of readers found this page helpful

Author information

Name: Merrill Bechtelar CPA

Birthday: 1996-05-19

Address: Apt. 114 873 White Lodge, Libbyfurt, CA 93006

Phone: +5983010455207

Job: Legacy Representative

Hobby: Blacksmithing, Urban exploration, Sudoku, Slacklining, Creative writing, Community, Letterboxing

Introduction: My name is Merrill Bechtelar CPA, I am a clean, agreeable, glorious, magnificent, witty, enchanting, comfortable person who loves writing and wants to share my knowledge and understanding with you.