Is it undefined behaviour to have a reference to freed memory?

Viewed 149

In C++, is it undefined behaviour to free memory that is still referred to by a reference, even if that reference is not used again? For example, does the following function invoke undefined behaviour?

void foo() {
    std::map<std::string, int> mymap;
    {
        int& val = mymap["eight"];
        val = 8;
        mymap.erase("eight"); // Oops! val still refers to mymap["eight"]
        // val is not used again
    }
    std::cout << "Entry count: " << mymap.size() << "\n";
}
2 Answers

From [associative.reqmts]p9, we see(emphasis mine):

The insert and emplace members shall not affect the validity of iterators and references to the container, and the erase members shall invalidate only iterators and references to the erased elements.

This is from N4659 [basic.stc]p4 1 (again, emphasis mine):

When the end of the duration of a region of storage is reached, the values of all pointers representing the address of any part of that region of storage become invalid pointer values (6.9.2). Indirection through an invalid pointer value and passing an invalid pointer value to a deallocation function have undefined behavior. Any other use of an invalid pointer value has implementation-defined behavior.

Although the text talks specifically about pointers, there is no reason to believe that it is not applicable to references(well, in a way they can be thought of as pointers). Also note the fact that it says "Any other use", so as long as you don't use the pointers/references in an expression after it has been invalidated, the behaviour should be well defined.


1 Note: Looks like this text was added in N4659 and doesn't seem to be present in earlier versions of the standard.

Is it undefined behaviour to have a reference to freed memory?

The standard doesn't define any behaviour for "having" any value of any type.


mymap.erase("eight"); // Oops! val still refers to mymap["eight"]

This is what the standard says about behaviour of erase:

[associative.reqmts] ... The erase members shall invalidate ... references to the erased elements ...

Note that the rule does not say that behaviour is undefined if those references exist. In fact, it would be rather pointless to describe that those references are invalidated if the existence of the reference would always imply undefined behaviour.

As for definition of what an invalid reference is... the standard appears to be lacking. There is a definition for invalid pointer, but I cannot find any for invalid reference. This lack of definition could be considered to be a defect in the standard.

Related