The C++ language creates the impression that holding a reference is stable, when in fact it is still possible for a reference to point to bogus memory (same as a dangling pointer). The C++ reference starts out on the right track with some nice compile-time guarantees like required initialization but then messes everything up by being immutable. The memory can be deallocated, and people with references are screwed; they cannot possibly change their own state to reflect the fact that the object is now gone. And C++ has some inconsistent hacks, such as the fact that a "const" reference to a temporary object will prevent object deallocation until scope exit but this is not the case for other uses of references.
Compare that behavior to something like Objective-C's "weak" properties, where ANY weak pointer to an object is set to 0 when the target object is destroyed. This guarantees that the property values will have one of two values: a pointer to valid memory, or "nil"; never a bogus pointer. In addition, Objective-C ignores messages sent to "nil". While clearly this can still create hurdles for debugging, it is fantastic for end users because the program itself is quite stable. The language created facilities for making invalid references hard, and mostly eliminated the penalty for screwing up.
Rust is stricter about references not being null, as in you get a compile time error if you try.