In C and C++, pointers are inherently unsafe, that is, when you dereference a pointer, it is your own responsibility to make sure it points somewhere valid; this is part of what "manual memory management" is about (as opposed to the automatic memory management schemes implemented in languages like Java, PHP, or the .NET runtime, which won't allow you to create invalid references without considerable effort).

A common solution that catches many errors is to set all pointers that don't point to anything as NULL (or, in correct C++, 0), and checking for that before accessing the pointer. Specifically, it is common practice to initialize all pointers to NULL (unless you already have something to point them at when you declare them), and set them to NULL when you delete or free() them (unless they go out of scope immediately after that). Example (in C, but also valid C++):

void fill_foo(int* foo) {
    *foo = 23; // this will crash and burn if foo is NULL
}

A better version:

void fill_foo(int* foo) {
    if (!foo) { // this is the NULL check
        printf("This is wrong\n");
        return;
    }
    *foo = 23;
}

Without the null check, passing a NULL pointer into this function will cause a segfault, and there is nothing you can do - the OS will simply kill your process and maybe core-dump or pop up a crash report dialog. With the null check in place, you can perform proper error handling and recover gracefully - correct the problem yourself, abort the current operation, write a log entry, notify the user, whatever is appropriate.

Answer from tdammers on Stack Exchange
Top answer
1 of 6
30

In C and C++, pointers are inherently unsafe, that is, when you dereference a pointer, it is your own responsibility to make sure it points somewhere valid; this is part of what "manual memory management" is about (as opposed to the automatic memory management schemes implemented in languages like Java, PHP, or the .NET runtime, which won't allow you to create invalid references without considerable effort).

A common solution that catches many errors is to set all pointers that don't point to anything as NULL (or, in correct C++, 0), and checking for that before accessing the pointer. Specifically, it is common practice to initialize all pointers to NULL (unless you already have something to point them at when you declare them), and set them to NULL when you delete or free() them (unless they go out of scope immediately after that). Example (in C, but also valid C++):

void fill_foo(int* foo) {
    *foo = 23; // this will crash and burn if foo is NULL
}

A better version:

void fill_foo(int* foo) {
    if (!foo) { // this is the NULL check
        printf("This is wrong\n");
        return;
    }
    *foo = 23;
}

Without the null check, passing a NULL pointer into this function will cause a segfault, and there is nothing you can do - the OS will simply kill your process and maybe core-dump or pop up a crash report dialog. With the null check in place, you can perform proper error handling and recover gracefully - correct the problem yourself, abort the current operation, write a log entry, notify the user, whatever is appropriate.

2 of 6
8

The other answers pretty much covered your exact question. A null check is made to be sure that the pointer you received actually points to a valid instance of a type (objects, primitives, etc).

I'm going to add my own piece of advice here, though. Avoid null checks. :) Null checks (and other forms of Defensive Programming) clutter code up, and actually make it more error prone than other error-handling techniques.

My favorite technique when it comes to object pointers is to use the Null Object pattern. That means returning a (pointer - or even better, reference to an) empty array or list instead of null, or returning an empty string ("") instead of null, or even the string "0" (or something equivalent to "nothing" in the context) where you expect it to be parsed to an integer.

As a bonus, here's a little something you might not have known about the null pointer, which was (first formally) implemented by C.A.R. Hoare for the Algol W language in 1965.

I call it my billion-dollar mistake. It was the invention of the null reference in 1965. At that time, I was designing the first comprehensive type system for references in an object oriented language (ALGOL W). My goal was to ensure that all use of references should be absolutely safe, with checking performed automatically by the compiler. But I couldn't resist the temptation to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years.

Top answer
1 of 5
15

Because a reference carries the semantic that it points to a valid memory address that never changes; i.e. that dereferencing it is safe/defined and so no NULL checks are required. References cannot be reassigned by design.

You use a pointer when the var can be NULL and client code has to handle that case. You use a reference when you can guarantee a valid/initialised memory address.

One example of using pointers is as a member of a class to store a "reference" to some instance that might not be known or able to be initialised at class construction time. However, member references must be initialised at construction time (via initialiser lists) and their assignment cannot be deferred.

If you allow a null reference it is then no different to a pointer besides syntax (the same NULL checks would need to take place.)

Update:

"And, in most OOP languages, objects can be NULL - Pascal, C#, Java, JavaScript, PHP, etc. [...] So why is C++ somehow special and doesn't have a NULL object? Was it just an overlook or an actual decision?"

I think you are a bit confused about this. Java and C# etc. might give the impression of "NULL objects", but these object references are more or less like a C++ pointer with simpler syntax, GC instrumentation and exception throwing. In those languages if you operate on a "Null Object" you will get some kind of exception like NullReferenceException (C#). Hell, in Java its called a NullPointerException.

You have to check for null before you can use them safely. Kind of like C++ pointers (except in most managed languages, pointers are initialised to NULL by default, whereas in C++ its usually up to you to take care of setting the initial pointer value (otherwise undefined/whatever memory was already there)).

The C++ view is about having choice, and hence being verbose:

  • Use a plain pointer to do how you please, checking NULL where necessary.
  • Use references which have a compiler-enforced validity semantic/constraint.
  • Roll your own smart pointers that do bookkeeping and behave whichever way you want them to.
  • Using void pointers (cautiously!) to reference an untyped block of memory if ever required.
2 of 5
6

Please have a look at differences between pointers and references - while the standard leaves it open how references are implemented, they are at the moment always implemented as pointers.

Which means that the main difference between them is a) semantics b) pointers can be reseated c) pointers can be null.

So the short answer is, this was done on purpose. When you as programmer see a reference you should know that a) that reference is populated b) it won't change (and c) you can use it with the same semantics as an object).

Would the standard allow a null reference, you would always have to check for null before using a reference, which was not wanted.

Edit:

Regarding your edit, I guess the confusion here might stem from the fact that most simpler OO languages hide what is going on. To take Java as example, while it looks like you have NULL objects, and can assign them, you really can't - what is really going on is that Java only has pointers, and can assign null values to those pointers. Since it is impossible to actually have objects directly in Java, they do away with pointer semantics and treat the pointer as the object. C++ is simply more powerful - and error prone (Java enthusiast would say that stack user class instances are not required, and the decision to not have them in Java was driven to reduce complexity, and make Java easier to use). It also follows that, since Java doesn't have objects, it doesn't have references. What really doesn't help, though, is that Java calls what a C++ person would call a pass-by-value of a pointer a pass-by-reference.

Discussions

c++ - Is a null reference possible? - Stack Overflow
Is this piece of code valid (and defined behavior)? int &nullReference = *(int*)0; Both g++ and clang++ compile it without any warning, even when using -Wall, -Wextra, -std=c++98, -pedantic, -... More on stackoverflow.com
🌐 stackoverflow.com
object - Returning a "NULL reference" in C++? - Stack Overflow
I return an object if it exists or null if not. What would be the equivalent in C++ using references? Is there any recommended pattern in general? More on stackoverflow.com
🌐 stackoverflow.com
Are you supposed to have Null reference checks a lot in your code? Are they common real world scenarios?
This has a philosophical answer. Simple "yes" and "no" don't do here. Ideally yes, every method should always check every parameter to make sure it is non-null, and any time you use any variable you should check for null. Following this to the letter makes your code extremely safe against one kind of error but is also very tedious. So every other answer is along a spectrum between yes and no. Most point out that checking for null everywhere adds a lot of redundant checks if your code has layers or long call chains. So they pick some way to define a "boundary" and argue anything "under" the boundary won't perform the checks and everything "above" the boundary will. This still falls apart in highly distributed scenarios as there end up being too many reasonable places to define boundaries. So I don't have a strict rule of thumb. When I'm writing code for myself I perform fewer checks. My assumption is I'm going to write unit tests and be reasonably sure I don't have nulls in unexpected locations, or that testing is going to quickly throw NullReferenceExceptions and I'll be able to fix them quickly. This is most true of my lowest-level "leaf" types because the higher I get in a call chain the more confident I am in saying, "The caller should have definitely validated before calling." At the very top level, such as my ViewModels in a WPF application, there's no "caller" to have done the validation so I'm more obsessive about null checks because I don't trust the user. But when the ViewModel passes valid data to a dependency I've unit tested and that dependency passes data to a third dependency, I tend to assume the thing I've unit tested didn't somehow generate null from valid data. If it did, I found a bug which means a new test and more confidence after fixing it. So I expect to see a lot more null checks at the top layers of library code and in the higher layers of GUI code. The deeper I get the less often I expect to see them, but I assume if I do see them it's evidence this layer deals with null more than I thought. (This is also influenced because I avoid using null as a valid value like the plague in my code unless it's completely unambiguous what it means and all code wants to treat every null the same way.) More on reddit.com
🌐 r/csharp
60
45
March 7, 2022
No, references are never null.

Just like this is never null. In fact, GCC will remove checks for null this because it can never be null.

More on reddit.com
🌐 r/cpp
162
95
March 1, 2018

In C and C++, pointers are inherently unsafe, that is, when you dereference a pointer, it is your own responsibility to make sure it points somewhere valid; this is part of what "manual memory management" is about (as opposed to the automatic memory management schemes implemented in languages like Java, PHP, or the .NET runtime, which won't allow you to create invalid references without considerable effort).

A common solution that catches many errors is to set all pointers that don't point to anything as NULL (or, in correct C++, 0), and checking for that before accessing the pointer. Specifically, it is common practice to initialize all pointers to NULL (unless you already have something to point them at when you declare them), and set them to NULL when you delete or free() them (unless they go out of scope immediately after that). Example (in C, but also valid C++):

void fill_foo(int* foo) {
    *foo = 23; // this will crash and burn if foo is NULL
}

A better version:

void fill_foo(int* foo) {
    if (!foo) { // this is the NULL check
        printf("This is wrong\n");
        return;
    }
    *foo = 23;
}

Without the null check, passing a NULL pointer into this function will cause a segfault, and there is nothing you can do - the OS will simply kill your process and maybe core-dump or pop up a crash report dialog. With the null check in place, you can perform proper error handling and recover gracefully - correct the problem yourself, abort the current operation, write a log entry, notify the user, whatever is appropriate.

Answer from tdammers on Stack Exchange
🌐
cppreference.com
en.cppreference.com › cpp › types › NULL
NULL - cppreference.com
January 3, 2025 - In C, the macro NULL may have the type void*, but that is not allowed in C++ because null pointer constants cannot have that type.
🌐
Wikipedia
en.wikipedia.org › wiki › Null_pointer
Null pointer - Wikipedia
June 13, 2026 - Because a null pointer does not ... crash. This is the null pointer error, or null pointer exception. It is one of the most common types of software weaknesses, and Tony Hoare, who introduced the concept, has referred to it as a "billion dollar mistake"....
Top answer
1 of 4
98

References are not pointers.

8.3.2/1:

A reference shall be initialized to refer to a valid object or function. [Note: in particular, a null reference cannot exist in a well-defined program, because the only way to create such a reference would be to bind it to the “object” obtained by dereferencing a null pointer, which causes undefined behavior. As described in 9.6, a reference cannot be bound directly to a bit-field. ]

1.9/4:

Certain other operations are described in this International Standard as undefined (for example, the effect of dereferencing the null pointer)

As Johannes says in a deleted answer, there's some doubt whether "dereferencing a null pointer" should be categorically stated to be undefined behavior. But this isn't one of the cases that raise doubts, since a null pointer certainly does not point to a "valid object or function", and there is no desire within the standards committee to introduce null references.

2 of 4
81

The answer depends on your view point:


If you judge by the C++ standard, you cannot get a null reference because you get undefined behavior first. After that first incidence of undefined behavior, the standard allows anything to happen. So, if you write *(int*)0, you already have undefined behavior as you are, from a language standard point of view, dereferencing a null pointer. The rest of the program is irrelevant, once this expression is executed, you are out of the game.


However, in practice, null references can easily be created from null pointers, and you won't notice until you actually try to access the value behind the null reference. Your example may be a bit too simple, as any good optimizing compiler will see the undefined behavior, and simply optimize away anything that depends on it (the null reference won't even be created, it will be optimized away).

Yet, that optimizing away depends on the compiler to prove the undefined behavior, which may not be possible to do. Consider this simple function inside a file converter.cpp:

int& toReference(int* pointer) {
    return *pointer;
}

When the compiler sees this function, it does not know whether the pointer is a null pointer or not. So it just generates code that turns any pointer into the corresponding reference. (Btw: This is a noop since pointers and references are the exact same beast in assembler.) Now, if you have another file user.cpp with the code

#include "converter.h"

void foo() {
    int& nullRef = toReference(nullptr);
    cout << nullRef;    //crash happens here
}

the compiler does not know that toReference() will dereference the passed pointer, and assume that it returns a valid reference, which will happen to be a null reference in practice. The call succeeds, but when you try to use the reference, the program crashes. Hopefully. The standard allows for anything to happen, including the appearance of pink elephants.

You may ask why this is relevant, after all, the undefined behavior was already triggered inside toReference(). The answer is debugging: Null references may propagate and proliferate just as null pointers do. If you are not aware that null references can exist, and learn to avoid creating them, you may spend quite some time trying to figure out why your member function seems to crash when it's just trying to read a plain old int member (answer: the instance in the call of the member was a null reference, so this is a null pointer, and your member is computed to be located as address 8).


So how about checking for null references? You gave the line

if( & nullReference == 0 ) // null reference

in your question. Well, that won't work: According to the standard, you have undefined behavior if you dereference a null pointer, and you cannot create a null reference without dereferencing a null pointer, so null references exist only inside the realm of undefined behavior. Since your compiler may assume that you are not triggering undefined behavior, it can assume that there is no such thing as a null reference (even though it will readily emit code that generates null references!). As such, it sees the if() condition, concludes that it cannot be true, and just throw away the entire if() statement. With the introduction of link time optimizations, it has become plain impossible to check for null references in a robust way.


TL;DR:

Null references are somewhat of a ghastly existence:

Their existence seems impossible (= by the standard),
but they exist (= by the generated machine code),
but you cannot see them if they exist (= your attempts will be optimized away),
but they may kill you unaware anyway (= your program crashes at weird points, or worse).
Your only hope is that they don't exist (= write your program to not create them).

I do hope that will not come to haunt you!

Top answer
1 of 10
57

You cannot do this during references, as they should never be NULL. There are basically three options, one using a pointer, the others using value semantics.

  1. With a pointer (note: this requires that the resource doesn't get destructed while the caller has a pointer to it; also make sure the caller knows it doesn't need to delete the object):

    SomeResource* SomeClass::getSomething(std::string name) {
        std::map<std::string, SomeResource>::iterator it = content_.find(name);
        if (it != content_.end()) 
            return &(*it);  
        return NULL;  
    }
    
  2. Using std::pair with a bool to indicate if the item is valid or not (note: requires that SomeResource has an appropriate default constructor and is not expensive to construct):

    std::pair<SomeResource, bool> SomeClass::getSomething(std::string name) {
        std::map<std::string, SomeResource>::iterator it = content_.find(name);
        if (it != content_.end()) 
            return std::make_pair(*it, true);  
        return std::make_pair(SomeResource(), false);  
    }
    
  3. Using boost::optional:

    boost::optional<SomeResource> SomeClass::getSomething(std::string name) {
        std::map<std::string, SomeResource>::iterator it = content_.find(name);
        if (it != content_.end()) 
            return *it;  
        return boost::optional<SomeResource>();  
    }
    

If you want value semantics and have the ability to use Boost, I'd recommend option three. The primary advantage of boost::optional over std::pair is that an unitialized boost::optional value doesn't construct the type its encapsulating. This means it works for types that have no default constructor and saves time/memory for types with a non-trivial default constructor.

I also modified your example so you're not searching the map twice (by reusing the iterator).

2 of 10
31

Why "besides using pointers"? Using pointers is the way you do it in C++. Unless you define some "optional" type which has something like the isNull() function you mentioned. (or use an existing one, like boost::optional)

References are designed, and guaranteed, to never be null. Asking "so how do I make them null" is nonsensical. You use pointers when you need a "nullable reference".

Find elsewhere
🌐
Cplusplus
cplusplus.com › reference › cstdio › NULL
NULL
A null-pointer constant is an integral constant expression that evaluates to zero (like 0 or 0L), or the cast of such value to type void* (like (void*)0).
🌐
W3Schools
w3schools.com › c › c_null.php
C NULL
C Examples C Real-Life Examples C Exercises C Quiz C Code Challenges C Practice Problems C Compiler C Syllabus C Study Plan C Interview Q&A ... NULL is a special value that represents a "null pointer" - a pointer that does not point to anything.
🌐
Microsoft Press Store
microsoftpressstore.com › articles › article.aspx
Understanding null values and nullable types
May 1, 2022 - Circle c = ...; // might be null, might be a new Circle object Circle c3 = ...; // might be null, might be a new Circle object ... var c3 ??= c; // Only assign c3 if it is null, otherwise leave unchanged; The null value is very useful for initializing reference types.
🌐
PVS-Studio
pvs-studio.com › en › blog › posts › csharp › 1049
NullReferenceException in C#. What is it and how to fix it?
May 2, 2023 - So when fixing code, it is useful to think about whether adding a check will be enough or whether something else needs to be fixed in the code. In addition to the fairly obvious tip "do not dereference null references", there are several practices that will help avoid the NRE exceptions.
🌐
Devot
devot.team › blog › null-reference-exception
The Billion-Dollar Coding Mistake: Understanding Null Reference Exceptions — Devōt
June 4, 2024 - Contents: Origins of the null reference concept · What does NULL signify? What is the null reference? Why are null values necessary for programming? What is the null reference exception? How do you get a null reference exception? Is there a difference between a null pointer exception (NPE) and a null reference exception?
🌐
Reddit
reddit.com › r/csharp › are you supposed to have null reference checks a lot in your code? are they common real world scenarios?
r/csharp on Reddit: Are you supposed to have Null reference checks a lot in your code? Are they common real world scenarios?
March 7, 2022 - I understand your angle of doing a large database lookup and having it all in one object, and the argument that form A is doing a lookup for form B, but really it’s just retrieving a single row from the database one time and displaying its info on the main form. The other forms simply read the data from the data row and react to it to set a couple combo box values mostly. ... I started using nullable reference types and I am loving it.
🌐
Reddit
reddit.com › r/cpp › no, references are never null.
r/cpp on Reddit: No, references are never null.
March 1, 2018 -

I just have to get this rant off my chest, since I've received a few comments about it on both my blog and an associated Reddit post.

Maybe I'm preaching to the choir. Maybe I'm feeding trolls. I'll assume that there are those out there who, in good faith, really don't understand that C++ references are not nullable.

Many other languages made the fatal error of permitting null as valid for all reference types, where every non-builtin is a reference type and they have boxing around classes. Here's some psuedo-Java:

class MyType {
  public void foo() {}
};

void my_fun(MyType instance) {
  instance.foo(); // <-- MAY THROW
}

void another_fun() {
  my_fun(null); // <-- explodes
}

This is semantically similar to the following C++:

class MyType {
public:
  void foo() {}
}

void my_fun(MyType* instance) {
  __check_nonnull(instance); // <-- Check inserted by compiler
  instance->foo();
}

void another_fun() {
  my_fun(nullptr);
}

With implicitly nullable references, every single use of the reference is a candidate for a nullptr.

On the contrary, C++ affords the guarantee that a T& always refers to a valid T.

Of course, all of C++'s guarantees have a caveat: Every guarantee goes out the window if any part of a program contains undefined behavior.

Here's a common "C++ null reference" example that detractors provide:

class MyClass {
public:
  void foo();
};

void do_thing(MyClass& inst) {
  inst.foo();
}

void other_thing() {
  MyClass* inst_ptr = nullptr;
  do_thing(*inst_ptr);
}

Of course, the fact that we dereference inst_ptr means the program behavior is undefined. The call inst.foo() is perfectly legal, and checking that &inst != nullptr is unnecessary.

In fact, the very expression &<anything> != nullptr is completely non-sensical. C++ guarantees that the builtin address-of operator& never returns nullptr. We even get a warning about it from GCC.

Saying "impossible thing might happen" is not useful. Imagine this code:

class MyClass {
public:
  void foo();
};

class UnrelatedClass {
public:
  void foo();
}

void do_thing(MyClass& inst) {
  inst.foo();
}

Saying "inst might be a null reference" is equivalent to saying "inst might actually be an UnrelatedClass" because someone might do this:

void garbage_fn() {
  UnrelatedClass garbage;
  do_thing(reinterpret_cast<MyClass&>(garbage));
}

Both cases are undefined, but for some reason, people still believe that null-references are a thing.

Edit: Wording


Edit to clarify:

I'm not saying that dereferencing null pointers never occurs in practice. What I'm really saying is that there is no use in worrying if a client has dereferenced a null pointer in order to fulfill a reference parameter on your API. There's no meaningful action that you can take.

🌐
Quora
quora.com › What-is-a-null-reference-exception
What is a null reference exception? - Quora
Answer (1 of 4): It is when you try to access a method or member from an object that is set to NULL. Consider this code (C++): [code]Foo *MyPtr = NULL; MyPtr->doStuff(); [/code]This will generate a null reference exception when running the code. Unfortunately you cannot detect this at compile ...
🌐
Medium
medium.com › dot-net-sql-learning › null-reference-exception-in-c-reason-and-how-to-fix-09511f9ed72a
Null Reference Exception in C#, Reason and How to fix | by Code Crack | Dot Net, API & SQL Learning | Medium
June 28, 2025 - Simply put, you are trying to access something that was not formally created in memory. This problem has become a headache for many developers and its solution depends on good programming practices. Did you know? The Null Reference Exception problem is called the “king of bugs” in programming.
🌐
Gotw
gotw.ca › conv › 002.htm
Conversations #2: Null References
Aboard ship, the last thing you want to feel is wind. Jeannine and I happened to be unlucky enough to be the closest to the incident; straining together, we managed to wrestle the bulky door shut and seal it, isolating the breached compartment. As we leaned against the door, breathing deeply, ...
🌐
Stackify
stackify.com › nullreferenceexception-object-reference-not-set
NullReferenceException: Object Reference Not Set
September 12, 2024 - When you try calling a method or another member on an empty variable, you get the NullReferenceException. You might now be wondering: if null references are so dangerous, why do they exist in the first place?
🌐
Medium
medium.com › @shlomohassid › null-how-do-you-define-nothing-and-why-would-you-07683bdbe63a
NULL: How Do You Define Nothing? And Why Would You? | by Momi | Medium
May 31, 2025 - This convenience had a huge catch: decades later, Hoare reflected on that decision and infamously dubbed it “my billion-dollar mistake”. He attributed countless system crashes, vulnerabilities, and hours of debugging to this single choice of allowing references to point to “nothing.” · Hoare’s null reference was quickly adopted in many languages (C, C++, Java, and more) because it was useful and easy to implement.