c++ - 引用已释放的内存是未定义的行为吗?

标签 c++ reference language-lawyer lifetime

在 C++ 中,释放仍然被引用引用的内存是否是未定义的行为,即使该引用不再使用?例如,以下函数是否会调用未定义的行为?

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";
}

最佳答案

从 [associative.reqmts]p9,我们看到(强调我的):

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.



这是来自 N4659 [basic.stc]p4 1 (再次强调我的):

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.



尽管文本专门讨论了指针,但没有理由相信它不适用于引用(好吧,在某种程度上,它们可以被认为是指针)。还要注意它说“ Any other use ”的事实,所以只要你在表达式失效后不使用指针/引用,行为就应该被很好地定义。

1 注意:看起来此文本是在 N4659 中添加的,并且似乎没有出现在标准的早期版本中。

关于c++ - 引用已释放的内存是未定义的行为吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62090015/

相关文章:

c++ - 对象能否从标准 C++ 容器中删除自身?

c++ - 在旧接口(interface)上创建新的 C++ 接口(interface)以添加新功能

c++ - 有没有办法将两个 QWidget 连接或锚定在一起?

c - int main() { }(没有 "void")在 ISO C 中有效且可移植吗?

c++ - 可以从同名的派生类函数调用基类函数。但我找不到支持这一点的标准引用

c++ - 声明和定义之间的冲突是否会导致未定义的行为?

c++ - WndProc 作为类方法

rust - 为什么借用的范围不是迭代器,但范围是?

visual-studio-2008 - 通过 NAnt 与 Visual Studio 构建 - 缺少一个 dll

java - 您如何证明数组类型是引用类型?