Is it possible to have a segmentation fault from a reference?

Yes, it's possible.

Foo& Fr = *(Foo*)nullptr;

Technically, this is already undefined behavior for dereferencing that pointer. But it most likely won't result in any observable error. This probably will though:

Fr.attr = 10;

However, as Jonathan Wakely points out in the comments, there is no reason for you to check for a case like this. If a function returns an invalid reference, that function is broken, and needs to be fixed. Your usage code is not broken for assuming that the reference is valid. However, a valid reference can become invalid (though not null) in perfectly legitimate code, as mentioned in the answer by David Schwartz. But there is no way for you to check for this. You simply need to know in what cases it can happen, and then stop using the reference.


A reference must refer to a valid object when that reference is seated. This is a C++ standard requirement and any code that violates it is UB (undefined behavior) and could do literally anything.

However, it is perfectly legal to destroy the object a reference refers to after that reference is seated. At that point, accessing the reference is illegal. For example:

std::vector<int> j;
j.push_back(3);
int& k = j.front(); // legal, object exists now
j.clear();         // legal, object may be destroyed while reference exists
k++;              // illegal, destruction of object invalidates reference

This means a function that returns a reference must always return a reference that's valid when it's returned. This is why calling front on an empty vector is UB -- a reference must be valid when it's seated. However, there will often be conditions that can subsequently invalidate that reference, and you need to understand what those conditions are if you plan to try to stash the reference and access it later.

Generally, you should assume that it's unsafe to stash a returned reference and access it later unless you know that the reference will remain valid. For example, std::vector carefully explains under what conditions a reference into the container can be invalidated, and that includes a subsequent call to push_back. So this is broken:

std::vector<int> j;
j.push_back(3);
int &first = j.front();
j.push_back(4);
int &second = j.back();
if (first == second) // illegal, references into container are invalidated by push_back

But this is fine:

std::vector<int> j;
j.push_back(3);
j.push_back(4);
int &first = j.front();
int &second = j.back();
if (first == second) // legal, references into container stay valid

Tags:

C++