C++资源池std::shared_ptr的use_count异常问题排查
以下是几种可能导致引用计数大于1的场景:
vector扩容引发的临时拷贝:当
vector因容量不足触发扩容时,会重新分配内存并复制原有元素。这个过程中,旧内存中的shared_ptr与新内存中的副本会同时指向同一资源,引用计数短暂升至2,直到旧内存中的shared_ptr被销毁后才会回落。哪怕使用std::move转移所有权,扩容时新元素构造完成到旧元素销毁的间隙,依然会存在两个有效引用。pop操作的返回值传递:若pop方法直接返回
shared_ptr<资源>,返回过程中会生成临时shared_ptr对象。如果调用方用变量接收返回值,那么临时对象与接收变量会短暂共存,此时引用计数会变为2,直到临时对象被销毁。测试逻辑引入额外引用:检测引用计数的代码可能无意中创建了
shared_ptr副本。比如直接拷贝资源池中的shared_ptr来调用use_count(),或者测试过程中保留了多余的shared_ptr实例,都会导致计数上升。未使用移动语义转移所有权:push或pop操作时,若直接拷贝
shared_ptr而非用std::move转移所有权,操作期间会存在两个指向同一资源的shared_ptr。例如调用push_back(ptr)而非push_back(std::move(ptr)),此时ptr仍持有资源引用,计数会维持为2直到ptr被重置或销毁。资源池访问时的意外拷贝:若其他线程或代码通过迭代器、
operator[]访问资源池并拷贝了shared_ptr(比如遍历过程中auto temp = pool[i];),只要拷贝出的shared_ptr未被销毁,引用计数就会大于1。
内容的提问来源于stack exchange,提问作者user2448758

