1.9、weak_ptr真的不计数?是否有计数方式,在哪分配的空间
std::weak_ptr本质上是不拥有对象所有权的智能指针,它不会增加对象的“强引用计数”(即shared_ptr的引用计数),因此不会直接影响对象的生命周期。但这并不意味着weak_ptr完全不计数,它确实维护了一个“弱引用计数”,用于跟踪当前有多少weak_ptr实例观察着同一个控制块(control block)。
控制块(Control Block)
shared_ptr
和weak_ptr
共享一个控制块,这个控制块里包含两个计数器:
- • 强引用计数(strong count):记录有多少
shared_ptr
实例拥有对象,决定对象的生存期。 - • 弱引用计数(weak count):记录有多少
weak_ptr
实例观察该对象,控制控制块本身的生命周期。
对象销毁时机
当最后一个shared_ptr
销毁时,强引用计数归零,对象被析构释放,但控制块不会立即销毁,必须等到所有weak_ptr
也销毁(弱引用计数归零)后,控制块才会被释放。这意味着对象内存释放与控制块内存释放是两个阶段。
内存分配
控制块通常是动态分配的,且在make_shared
的实现中,控制块和对象可能被分配在同一块内存中(内存共置),以提升性能和减少内存碎片。这也解释了为什么即使对象被销毁,若还有weak_ptr
存在,内存不会完全释放。
为什么需要弱引用计数?
虽然weak_ptr
不影响对象的生命周期,但它必须知道控制块何时可以安全销毁。弱引用计数确保控制块在所有shared_ptr
和weak_ptr
都销毁后才释放,避免悬空指针和内存错误。
总结
特性 | shared_ptr | weak_ptr |
是否拥有对象所有权 | 是,增加强引用计数 | 否,不增加强引用计数 |
是否维护计数 | 是,维护强引用计数和弱引用计数 | 是,维护弱引用计数 |
控制块生命周期 | 控制对象生命周期,控制块由弱引用计数控制 | 观察控制块,影响控制块释放时机 |
内存分配 | 控制块和对象通常动态分配,make_shared 可共置 |
共享控制块,不单独分配内存 |
因此,weak_ptr
“不计数”是指它不增加对象的强引用计数,不延长对象生命周期,但它确实维护弱引用计数,参与控制块的生命周期管理。
本文首发于【讳疾忌医-note】公众号,未经授权,不得转载。
(加入我的知识星球,免费获取账号,解锁所有文章。)
阅读剩余
版权声明:
作者:讳疾忌医-note
链接:https://www.1217zy.vip/archives/1192
文章版权归作者所有,未经允许请勿转载。
THE END