std::unique_ptr转移所有权后调用原指针方法是否为未定义行为?
为什么std::unique_ptr所有权转移后原指针还能调用成员函数?
首先明确结论:p1在通过std::move转移所有权后已经变成空指针,调用p1->foo()属于未定义行为,只是你的代码刚好没触发崩溃而已,这完全是侥幸情况。
具体原因拆解:
- 非虚成员函数的调用逻辑:C++的非虚成员函数是编译期绑定地址的,
p1->foo()本质上等价于把p1作为this指针传递给Car::foo函数。如果成员函数内部没有访问任何成员变量,也没有间接使用this指针指向的内存区域,那么即使this是空指针,函数也可能正常执行——因为它不需要触碰那块无效的内存。你的foo()只是打印固定字符串,完全没用到成员变量或this指向的内存,所以侥幸跑通了。 - 访问成员变量的区别:当你写
p1->data时,等价于先对空指针p1解引用(*p1),再访问成员data。这一步需要访问空指针指向的内存区域(此时该内存要么已经被释放,要么不属于当前进程),直接触发了内存访问违规,也就是你看到的段错误。
重要提醒:
绝对不要依赖这种“看起来能运行”的未定义行为。未定义行为的结果是不可预测的——这次能正常打印,下次可能直接崩溃,或者程序出现诡异的逻辑错误,甚至在不同编译器、不同平台下表现完全不一致。只要std::unique_ptr被move后,原指针就应该被视为无效,禁止再使用。
内容的提问来源于stack exchange,提问作者Fox1942
相关产品推荐
相关产品推荐

