对象进入析构函数后的状态及析构期间使用对象的合法性问询
问题分析与解答
相关代码
A::~A() { b.foo(this); }
void B::foo(A*) { // 尝试获取锁 // 从某个状态中移除A对象 }
void B::bar() { // 尝试获取锁 // 对A对象执行一些操作 }
核心问题解答
1. bar()中继续使用已触发析构的A对象是否合法?
不合法。根据C++标准,对象的生命周期从构造函数执行完毕时开始,到析构函数开始执行时终止。一旦A对象的析构函数被调用,该对象就不再是有效的完整对象,此时对其进行任何非析构流程内的操作(比如在bar()中访问它的成员、调用它的非静态成员函数)都属于未定义行为。
2. 额外风险:死锁
场景中还存在明确的死锁风险:线程调用bar()并持有锁后,A对象触发析构,析构函数调用B::foo()尝试获取同一锁。如果使用的是不可重入锁,当前线程会因重复获取已持有的锁而阻塞,导致bar()无法释放锁、析构函数也无法完成,最终形成死锁。
即使锁是可重入的,foo()成功移除A对象后,bar()继续操作该对象依然会触发未定义行为,因为对象的生命周期已经结束。
内容的提问来源于stack exchange,提问作者user129393192
相关产品推荐
相关产品推荐

