C++传递std::shared_ptr到weak_ptr参数线程的疑似bug咨询
结论与解决方案
这不是标准库的实现Bug,是你对std::thread的参数传递机制存在误解。
现象原因解释
std::thread的构造逻辑是:先复制/移动所有传入的参数,存储到线程内部的参数缓冲区里,等到线程实际启动执行时,才会把存储的参数传给目标函数做类型转换匹配。
你示例中的调用方式存在的问题:
- 直接给
std::thread构造函数传入std::shared_ptr<int>类型的p,会先触发shared_ptr的复制构造,线程内部生成一个shared_ptr副本,强引用计数直接+1 - 后续主线程把p置为nullptr仅减少1次强引用,线程内部的shared_ptr副本还在持有强引用,对应资源的强引用计数始终为1不会被释放,因此
weak_ptr.lock()可以拿到有效指针,输出"pw alive"
正确修改方案
你需要在把参数传给std::thread之前,就主动把shared_ptr转为weak_ptr,避免线程内部持有强引用,仅需要修改main函数中线程构造的代码即可:
std::thread t(TestWeakPtrAlive, std::weak_ptr<int>(p));
修改后线程内部存储的是weak_ptr副本,不会增加资源的强引用计数,主线程把p置为nullptr后强引用计数归0,资源正常释放,程序会输出预期的"pw dead"。
标准库Bug反馈渠道
如果后续你确认遇到了标准库实现的Bug,可以通过以下渠道反馈:
- Visual Studio的STL实现问题,反馈到微软开发者社区
- GCC的libstdc++实现问题,反馈到GCC官方Bug跟踪平台
内容的提问来源于stack exchange,提问作者V. Semeria
相关产品推荐
相关产品推荐

