共享所有权
一个动态分配的对象可以在多个shared_ptr
之间共享,这是因为shared_ptr
支持 copy 操作:
原理介绍
shared_ptr
内部包含两个指针,一个指向对象,另一个指向控制块(control block),控制块中包含一个引用计数和其它一些数据。由于这个控制块需要在多个shared_ptr
之间共享,所以它也是存在于 heap 中的。shared_ptr
对象本身是线程安全的,也就是说shared_ptr
的引用计数增加和减少的操作都是原子的。
通过unique_ptr
来构造shared_ptr
是可行的:
shared_ptr 的风险
你大概觉得使用智能指针就再也高枕无忧了,不再为内存泄露烦恼了。然而梦想总是美好的,使用shared_ptr
时,不可避免地会遇到循环引用的情况,这样容易导致内存泄露。循环引用就像下图所示,通过shared_ptr
创建的两个对象,同时它们的内部均包含shared_ptr
指向对方。
分析一下main
函数是如何退出的,一切就都明了:
main
函数退出之前,Father
和Son
对象的引用计数都是2
。son
指针销毁,这时Son
对象的引用计数是1
。father
指针销毁,这时Father
对象的引用计数是1
。- 由于
Father
对象和Son
对象的引用计数都是1
,这两个对象都不会被销毁,从而发生内存泄露。
为避免循环引用导致的内存泄露,就需要使用weak_ptr
,weak_ptr
并不拥有其指向的对象,也就是说,让weak_ptr
指向shared_ptr
所指向对象,对象的引用计数并不会增加: