The vulnerability as described in ISO/IEC TR 24772-1:2019 clause 6.13 exists in C++. Dereferencing a pointer with the value of nullptr is undefined behavior [EWF].
Using pointers is inherently problematic especially for function parameters and return values, due to the following issues:
nullptr value valid in context?nullptr value?T[] as a function parameter type is identical to T*)Using values instead of pointers sidesteps all pointer vulnerabilities, especially when returned from a function. For example, standard library containers like std::vector have value semantics and do not suffer from this vulnerability.
C++ references cannot be null in a well-defined program and solve the null-dereferencing vulnerability. They are particularly useful as function parameters. Using a reference as function return type requires the caller to avoid accessing an object outisde of its lifetime (see [XYK], [DCM]).
If absence of a value is necessary, a class type for optional values such as std::optional provides well-defined behaviour and single-object ownership. In case of attempting to access the value of an empty std::optional an exception is thrown.
Note: Be aware that optional<T&> is not supported by the standard library. For representing optional references std::optional<std::reference_wrapper<T>> or a non-standard implementation of optional supporting references can be used.
If dynamically allocated objects are required, std::unique_ptr<T> can be used for lifetime-management and for transferring ownership. When shared ownership of such objects is necessary, std::shared_ptr<T> is a solution. Using std::shared_ptr<T const> provides value semantics for immutable heap-allocated objects thus sidestepping most of the issues of pointers above. Constructing a smart pointer through the factories std::make_unique or std::make_shared will return a non-null smart pointer or throw an exception and thus prevent the vulnerability of null pointers, in contrast to legacy allocation mechanisms and some overloads of operator new. However, in general dereferencing a std::unique_ptr or std::shared_ptr equal to nullptr causes undefined behaviour, for example, when such a smart pointer is default constructed or a std::unique_ptr is in a moved-from state. For further information see also [XYL].
To avoid the vulnerability or mitigate its ill effects, C++ software developers can:
Avoid the need for pointers by using values.
Prefer references over pointers for parameters.
Use std::optional instead of a pointer to represent a potentially empty value.
Use containers with value semantics instead of plain arrays such as std::array, std::vector.
Use make_unique() or make_shared() for dynamically allocating objects.
If using objects of pointer-like types that may be a nullptr value is unavoidable, use the avoidance mechanisms of ISO/IEC 24772-1 clause 6.13.5.
Use static and dynamic analysis tools to detect potential violations of this guideline.