nullptr in C++ is the modern way to represent a null pointer. It was introduced in C++11 to solve a long-standing problem with older null pointer representations such as 0 and NULL. Before nullptr, programmers often used integer-like values to mean that a pointer was not pointing to any valid object. That worked in many simple cases, but it also created ambiguity, especially in overloaded functions and template code. nullptr fixed that design weakness by giving C++ a dedicated null pointer literal with a real type.
This topic matters because pointers are foundational in C++. The moment you work with dynamic memory, function parameters, linked structures, optional ownership, or APIs that may or may not return an object, you will encounter the idea of a pointer that points to nothing. If that concept is expressed loosely, code becomes harder to read and easier to break. If it is expressed correctly with nullptr, intent becomes clearer, overload resolution becomes safer, and the code becomes more modern and more maintainable.
What Is nullptr in C++?
nullptr is a keyword in C++ that represents a null pointer literal. It means the pointer does not currently refer to any valid memory address of an object or function. Unlike 0 and NULL, nullptr is not just an integer-looking value that happens to be used as a pointer in many places. It is a dedicated language feature created specifically for null pointers.
The type of nullptr is std::nullptr_t. Because it has its own type, the compiler can distinguish it from normal integers. That is the main reason it behaves more safely in modern C++ programs.
nullptris the C++ null pointer literal, and its purpose is to express pointer emptiness without the ambiguity of integer-based null values.
Why nullptr Was Introduced
Before C++11, programmers usually wrote 0 or NULL to indicate a null pointer. The problem is that both of these can behave like integers. In many compilers, NULL is just a macro that expands to 0 or 0L. So although developers intended to say “this is not a valid pointer,” the compiler often saw “this is an integer constant.”
- That ambiguity could confuse overloaded functions.
- It could make APIs less expressive.
- It could produce subtle bugs in generic code.
- It made the language less precise than it should have been.
C++11 introduced nullptr so that a null pointer could be represented by a true pointer literal rather than by an integer constant that happened to be treated like a pointer in some contexts.
nullptr vs NULL vs 0
All three may be used to represent the idea of “no object,” but they are not equally good in C++.
| Representation | Meaning | Main Issue |
|---|---|---|
0 | Integer literal that can act as null pointer constant | Looks like an integer, not a pointer |
NULL | Macro, often expanding to 0 | Usually still integer-based and ambiguous |
nullptr | Dedicated null pointer literal | No integer ambiguity; preferred in modern C++ |
If you are writing modern C++, use nullptr. It communicates intent more clearly and gives the compiler better information.
Basic Syntax of nullptr
You can assign nullptr to a pointer exactly the way you would assign a null state to any pointer variable.
int* ptr = nullptr;
char* buffer = nullptr;
double* value = nullptr;
Each of these pointers is valid as a variable, but none of them currently points to an actual object. That means you can compare them, reassign them, and check them in conditions, but you must not dereference them until they point to valid memory.
Checking a Pointer Against nullptr
One common use of nullptr is to test whether a pointer currently holds a valid address.
int* ptr = nullptr;
if (ptr == nullptr)
{
std::cout << "Pointer is null" << std::endl;
}
You will also see this written in shorter form because a null pointer converts to false in a boolean context.
if (!ptr)
{
std::cout << "Pointer is null" << std::endl;
}
Both forms are correct. The explicit comparison is often easier for beginners to read, while the shorter form is common in experienced codebases.
Why nullptr Is Safer in Function Overloading
One of the best reasons to use nullptr is overload resolution. Because 0 is an integer, it can call an integer overload when the programmer really intended to call a pointer overload. nullptr removes that ambiguity.
#include <iostream>
using namespace std;
void show(int value)
{
cout << "Integer overload" << endl;
}
void show(int* ptr)
{
cout << "Pointer overload" << endl;
}
int main()
{
show(0); // Calls integer overload
show(nullptr); // Calls pointer overload
}
This is a major language-level benefit. nullptr does not just improve style. It improves correctness.
Using nullptr with Dynamic Memory
When working with dynamic memory, nullptr is commonly used both before allocation and after deallocation. This does not replace good ownership design, but it does make pointer state more explicit.
int* data = nullptr;
data = new int(42);
std::cout << *data << std::endl;
delete data;
data = nullptr;
After delete, setting the pointer to nullptr helps prevent accidental reuse of a dangling value. It does not magically fix lifetime mistakes in shared ownership situations, but it is still a reasonable defensive habit for simple raw-pointer code.
The Type of nullptr: std::nullptr_t
A detail that makes nullptr special is that it has its own type: std::nullptr_t. This type can convert to any raw pointer type and any pointer-to-member type, but it does not behave like a normal integer type. That gives the compiler a much more precise signal about what the programmer intends.
#include <cstddef>
std::nullptr_t np = nullptr;
You will not often declare variables of type std::nullptr_t directly in beginner code, but knowing that the type exists helps explain why overload resolution and template deduction behave better with nullptr than with 0 or NULL.
Can You Dereference nullptr?
No. Dereferencing nullptr is undefined behavior because there is no valid object there. A null pointer explicitly means “this pointer does not point to an object right now.”
int* ptr = nullptr;
// Wrong
// std::cout << *ptr;
This kind of bug can cause a crash, but undefined behavior is broader than crashing. In some builds it may seem to work for a while, which is even worse because it creates false confidence.
Common Use Cases of nullptr
- Initializing pointers to a safe empty state before they are assigned a real object.
- Returning “no object found” from pointer-returning functions.
- Resetting raw pointers after releasing dynamic memory in simple code.
- Checking whether a function parameter points to a valid object before using it.
- Expressing optional pointer relationships clearly in APIs.
In each of these cases, nullptr makes the code self-explanatory. A reader instantly understands that the pointer intentionally points to nothing.
Best Practices for nullptr in Modern C++
- Prefer
nullptrinstead ofNULLor0in all modern C++ code. - Initialize raw pointers with
nullptrif they do not immediately point to a valid object. - Check pointers before dereferencing when null is a valid state.
- Use references instead of pointers when null should never be allowed.
- Prefer smart pointers and containers when ownership is involved instead of manually managing raw pointers everywhere.
That last point matters. nullptr improves raw pointer semantics, but good C++ design also depends on using the right ownership model. Modern C++ often reduces raw pointer usage by favoring RAII, smart pointers, and standard containers.
nullptr in Function Parameters and Return Values
nullptr is often useful in APIs that allow the absence of an object. A function can accept a pointer parameter and use nullptr to mean that the caller is intentionally not providing an object. A pointer-returning function can also return nullptr to show that no valid result is available.
int* findValue(bool found)
{
if (!found)
{
return nullptr;
}
return new int(99);
}
This style makes the contract clearer than returning 0 because the result is visibly pointer-related. It also forces the caller to think about the null case before dereferencing the returned pointer.
nullptr with Smart Pointers
Modern C++ still uses the idea of nullness even when raw pointers are replaced by smart pointers. A std::unique_ptr or std::shared_ptr can also be empty, and nullptr is the standard way to express that empty state.
#include <memory>
std::unique_ptr<int> ptr = nullptr;
if (ptr == nullptr)
{
ptr = std::make_unique<int>(25);
}
This matters because nullptr is not tied only to old raw-pointer code. It is part of the larger C++ model for representing “no pointee exists right now,” whether ownership is manual or automatic.
Common Mistakes Related to nullptr
- Using
NULLin new code even thoughnullptris clearer and safer. - Assuming a pointer has a valid target without checking whether
nullptris allowed by the API contract. - Using pointers where a reference would better express that null is never acceptable.
- Thinking that assigning
nullptrautomatically fixes ownership problems after a bad delete pattern.
A useful rule is this: if “no object” is a meaningful state, a pointer and nullptr may be appropriate. If “no object” should never happen, a reference often communicates intent better. That distinction improves readability and prevents entire classes of null-handling mistakes.
nullptr in Boolean Context
A null pointer evaluates to false in conditions, while a non-null pointer evaluates to true. That is why both if (ptr == nullptr) and if (!ptr) are valid. The important part is consistency and readability. In teaching code, the explicit comparison is often clearer. In compact production code, the shorter boolean form is also common.
Important Things to Remember About nullptr
nullptrwas introduced in C++11.- It is the preferred null pointer literal in modern C++.
- Its type is
std::nullptr_t. - It avoids the overload ambiguity of
0andNULL. - It can be assigned to pointer types, but it must never be dereferenced.
Continue learning C++ in order
Follow the topic sequence with the previous and next lesson.