子线程访问被主线程delete掉的共享对象
class A{
public:
A(int val = 100){ std::cout<<"A()"<<std::endl; ptr_ = new int; *ptr_ = val; }
~A() { std::cout<<" ~A()"<<std::endl; }
void show(){ cout<<"*ptr_ = "<<*ptr_<<endl; }
private:
int *ptr_;
};
void ThreadFunction(A *p){
std::this_thread::sleep_for(std::chrono::seconds(3));
//睡眠保证主线程将共享对象p析构掉
p->show();
//子线程中访问已经被主线程析构掉的对象的方法
}
int main(){
A *p = new A(9999999);
thread t1(ThreadFunction,p);
delete p;
t1.join();
return 0;
}
上面的代码很简单,也很好理解,执行结果如下(不同平台结果可能不同,但是结果最终肯定是意料之外的):
A()
~A()
段错误 (核心已转储)
利用weak_ptr能否提升为强指针的特点来判断、检查共享对象是否还存在:
class A{
public:
A(int val = 100){ cout<<"A()"<<endl; ptr_ = new int; *ptr_ = val; }
~A() { cout<<" ~A()"<<endl; }
void show(){ cout<<"*ptr_ = "<<*ptr_<<endl; }
private:
int *ptr_;
};
void ThreadFunction(weak_ptr<A> p){
std::this_thread::sleep_for(std::chrono::seconds(3));
shared_ptr<A> ptr = p.lock();
if(ptr != nullptr){
cout<<"Object still exists!!!"<<endl;
ptr->show();
}else{
cout<<"shared object has been deleted!!!"<<endl;
}
}
int main(){
{
shared_ptr<A> ptr (new A(8888));
thread t1(ThreadFunction,weak_ptr<A>(ptr));
t1.detach();
}//出作用域 ptr资源释放,共享对象不存在
std::this_thread::sleep_for(std::chrono::seconds(10));
return 0;
}
执行结果:
A()
~A()
shared object has been deleted!!!
总结:
- 如果共享对象存在,弱智能指针就可以成功提升为强智能指针,就可以用提升后的指针访问共享资源;
- 如果共享对象不存在,我们无法将弱智能指针提升,就不能去访问共享对象;
- 关键点:
lock()
方法返回值是否为nullptr
.