reference_wrapper: Is this UB?
reference_wrapper: Is this UB?
我很好奇这段代码是否是UB。
https://wandbox.org/permlink/nU0iPLCrPXwQ7Kor
代码不会崩溃(在GCC和Clang中,无论是否进行优化(,这让我越来越困惑。。
#include <list>
#include <vector>
#include <iostream>
#include <utility>
#include <queue>
using namespace std;
int main() {
deque<int> l {1, 2, 3, 4, 5};
vector<reference_wrapper<int>> v (l.begin(), l.end());
// v now holds references to 1, 2, 3, 4, 5 in l
cout << v[3] << 'n'; // 4
l.pop_front(); // 1 popped
for (auto num : l) {
cout << num << ' '; // 2 3 4 5
}
cout << 'n';
cout << v[0] << 'n'; // I think this should crash because 1 is dangling reference
l.pop_front(); // 2 popped
for (auto num : l) {
cout << num << ' '; // 3 4 5
}
cout << 'n';
cout << v[1] << 'n'; // I think it should crash but it still outputs 2
}
我很好奇这段代码是否是UB。
是的,由于使用了悬空引用,这显然是未定义的行为。
未定义的行为意味着任何1都可能发生,包括但不限于提供预期输出的程序。但是永远不要依赖(或根据未定义行为的程序的输出得出结论(。
所以您看到的输出是未定义行为的结果。但正如我所说,不要依赖于有UB的程序的输出。该程序可能导致分段错误。
使程序正确的第一步是删除UB然后并且只有到那时您才能开始对程序的输出进行推理。
1对于未定义行为的更准确的技术定义,请参阅此处,其中提到:对程序的行为没有限制
您的代码之所以没有崩溃,是因为您在deque的实现细节方面很幸运。
deque以512字节的块为单位分配内存。deque中的第一个和最后一个块可以分别在它们的前面或后面部分填充。指针标记这些位置。pop_front只是将指针向前移动一个元素,只要第一个块不是完全空的。
在您的示例中,完整的内容可以放在一个块中。因此,您只需继续引用仍然分配的内存,并且deque认为这些内存是空的。当然,任何诸如push_front或任何其他调整大小的操作都可能改变这一点。
相关文章:
- 表示"accepting anything for this template argument" C++概念的通配符
- 为什么使用 "this" 指针调用派生成员函数?
- C++错误:"error: int aaa::bbb is protected within this context"
- 我可以将调用类的"this"传递给 lambda 函数吗?
- 创建具有 new in 函数和"this is nullptr"异常的对象
- 关于C++中具有多重继承"this"指针的说明
- 在noexcept 规范中是否允许使用"this"?
- 如何修复"error: ‘_1’ was not declared in this scope"?
- 'string.assign(string.data(), 5)' 是明确定义的还是 UB?
- C++调用具有 *this 属性的单个帮助程序函数
- Doees the 'this' 指针参与虚函数的多态行为
- 在 c++ 中正确定义"this"关键字?
- 使用 CTRP 时,是否访问访问父构造函数 UB 中的子属性?
- 在什么情况下,两个堆栈分配的结构对象的 this 点指向同一个地址?
- "Unable to start debugging. No process is associated with this object." - 在Visual Studio Code中使用GDB
- 为什么我会收到此错误?无法将 {lb, ub} 从<大括号括起来的初始值设定项列表>转换为 float(**)(float*, int)
- QObject::连接无法将信号连接到*this*对象的插槽
- 析构函数中的"delete this"
- 为什么成员函数内的"this"指针为空?
- 在基本构造函数完成之前传递“this”:UB 或只是危险