子線程訪問被主線程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
.