ZhangJie Software Development Engineer

利用shared_ptr与weak_ptr解决空悬指针问题

2021-01-31
ZhangJie

在多线程开发中,有两个指针p1和p2,指向堆上的同一个对象obj, 当对象obj被线程A通过指针p1销毁后, p2就变成了空悬指针,当线程B通过指针p2访问对象obj时,如何判断对象obj是否存活呢?通过C++11中的std::shared_ptr与std::weak_ptr能够非常容易的解决该问题。

空悬指针问题示例

std::vector<Observer*> obs;
Observer* o1 = new Observer("o1");
obs.push_back(o1);

delete o1;     // 销毁o1指向的对象
o1 = nullptr;  // 置nullptr没啥用

for (auto o : obs)
{
    if (o)   // 判断是否为nullptr没啥用
    {
        o->update();   // 0xC0000005: 读取位置 0xDDDDDDDD 时发生访问冲突。
    }
}

空悬指针问题解决示例

std::vector<std::weak_ptr<Observer>> obs;

{
    std::shared_ptr<Observer> o1 = std::make_shared<Observer>("o1");
    obs.push_back(o1);  // 离开本作用域,o1指向的对象即将销毁
}
    
for (auto o : obs)
{
    std::shared_ptr<Observer> spo(o.lock());  // 尝试提升,线程安全
    if (spo) 
    {
        // 提升成功    
        spo->update();  // spo在栈上,对象不可能在本作用域内销毁
    }
}

Comments

Content