当shared_ptr的实例仍在作用域中时,共享指针的对象被删除

object of shared pointer being deleted while instances of shared_ptr are still in scope

本文关键字:共享 指针 对象 删除 作用域 shared ptr 实例      更新时间:2023-10-16

我有一个STL映射,它包含指向在多个线程中操作的对象的共享指针。shared_ptr拥有的对象正在被删除,而智能指针仍存在于容器和/或其他函数的作用域中。所有shared_ptr实例都是通过值传递的(因此引用的滥用不是问题)。我从这里的这个来源得到的印象是,只要shared_ptr的实例存在(它是从现有的shared_ptr复制的),它所拥有的对象就不会被释放。

这基本上就是我正在做的:

/* Remove Event response in Thread A */
std::map<std::string, std::shared_ptr<object>>::iterator it = objects.find(id);
if(it != objects.end())
{
    std::shared_ptr<object> ob = it->second;
    objects.erase(it);
    //Do cleanup work with ob
}
/* Add Event response in Thread B */
std::map<std::string, std::shared_ptr<object>>::iterator it = objects.find(id);
if(it == objects.end())
{
    std::shared_ptr<object> ob(new object(id));
    objects[id] = ob;
    //Do setup work with ob
}
/* Duty Cycle Event response in Thread C (very frequent) */
//Take snapshot of objects so Remove Event does not invalidate iterators of duty cycle
std::map<std::string, std::shared_ptr<object>> temp_objects = objects; 
for(std::map<std::string, std::shared_ptr<object>>::const_iterator it = temp_objects.begin(); it != temp_objects.end(); ++it)
{
    std::shared_ptr<object> ob = it->second;
    //Access violation can (but doesn't always) occur when dereferencing ob (ob is empty)
}

我做错了什么?我是否滥用了共享指针,或者对它们的操作方式做出了不正确的假设?

shared_ptr对象的引用计数是原子计数;这是C++11所要求的。但是,不需要的是std::map操作是原子操作。他们当然不是。

不能保证您可以从一个线程插入和从另一个线程删除,并且仍然保持map内容的完整性。因此,除非您放入自己的互斥对象或其他同步,以防止map本身出现竞争条件,否则您的代码将中断。

这与shared_ptr无关;这只是问题的症状。这是关于包含它们的map