Dereferencing a null pointer results in undefined behavior.
Why is this an issue?
A pointer to null, also known as a null pointer, is created by initializing a pointer object to 0
, NULL
, or in the case
of C++ nullptr
. A null pointer does neither point to an object nor to valid memory, and as a consequence dereferencing or accessing the
memory pointed by such a pointer is undefined behavior.
int deref() {
int* ptr = 0;
return *ptr; // Noncompliant: deference of a null pointer
}
In addition to using the *
operator, accessing a member of a structure (using →
) or an element of an array (using
[]
) also leads to dereference of the pointer, and causes undefined behavior if performed on a pointer to null.
int subscript() {
int* ptr = 0;
return ptr[2]; // Noncompliant: subscript operator used on null pointer
}
struct Aggregate {
int x;
int y;
};
int memberAccess() {
struct Aggregate* ptr = 0;
return ptr->x; // Noncompliant: member access on a null pointer
}
Finally, invoking a function pointer that holds a null value, dereferences the pointer, and too results in undefined behavior.
void call() {
void (*func)(int) = NULL; // func is a pointer to a function
func(10); // Noncompliant: the invocation of a null function pointer
}
What is the potential impact?
The behavior of a program that dereferences a null pointer is undefined. In that case, the compiler no longer needs to adhere to the language
standard and the program has no meaning assigned to it.
In practice, dereferencing a null pointer may lead to program crashes, or the application may appear to execute correctly while losing data or
producing incorrect results.
Besides affecting the application’s availability, null pointer dereferences may lead to code execution, in rare circumstances. If null is
equivalent to the 0x0
memory address that can be accessed by privileged code, writing, and reading memory is possible, which compromises
the integrity and confidentiality of the application.
How to fix it
Ensure that any pointer that is dereferenced by the program is not null.
Code examples
Noncompliant code example
char *p1 = ... ;
if (p1 == NULL && *p1 == '\t') { // Noncompliant: p1 will be dereferenced IFF it is null
// ...
}
Compliant solution
char *p1 = ... ;
if (p1 != NULL && *p1 == '\t') { // Compliant: *p1 cannot be evaluated if p1 is NULL
// ...
}
Noncompliant code example
char *p2 = ... ;
if (p2 != NULL) {
// ...
}
p2[2] = '\t'; // Noncompliant: potential null-dereference
Compliant solution
char *p2 = ... ;
if (p2 != NULL) {
// ...
p2[2] = '\t'; // Compliant: p2 is known to be non-null
}
Going the extra mile
In C++, it is preferred to use reference parameters (Type const&
or Type&
), or pass objects by value
(Type
), instead of a pointer (Type const*
or Type*
), if the argument is expected to never be null.
// Precondition: graph != null
bool isDAG(Graph const* graph);
The preferred signature would be:
bool isDAG(Graph const& graph);
Resources
Standards
External coding guidelines
Related rules
- S3807 detects calls to C library functions that require valid, non-null pointers with null pointer arguments
- S2637 detects uses of null pointers as arguments for parameters that are annotated with
nonnull