shared_ptr共享被管理对象,同一时刻可以有多个shared_ptr拥有对象的所有权,当最后一个shared_ptr对象销毁时,被管理对象自动销毁
shared_ptr 实现
简单来说,shared_ptr实现包含了两部分,
一个指向堆上创建的对象的裸指针,raw_ptr
一个指向内部隐藏的、共享的管理对象。share_count_object
第一部分没什么好说的,第二部分是需要关注的重点:
use_count,当前这个堆上对象被多少对象引用了,简单来说就是引用计数。
weak_count,这个管理对象被多少个智能指针共享了,简单来说就是管理对象的引用计数。
不同指针创建的对同一个堆上对象的智能管理,并不共享管理对象,因此存在double free的可能性
_shared_ptr直接包含的裸指针,即raw prt,是为了实现一般指针的->,*等操作,通过__shared_count object间接包含的指针是为了管理对象的生命周期,回收相关资源。
换句话说,__shared_count object内部的use_count主要用来标记被管理对象的生命周期,weak_count主要用来标记管理对象的生命周期。
注意区分管理和被管理。
问题原因
了解了原理,可以看出std::share_ptr本身的raw ptr指向了堆上通过new创建的对象。但是其自身这个raw ptr却会如果在不当操作上,被修改,比如栈越界操作,就会被破坏,导致产生对非法对象的访问:
上述这段代码就会引发问题,这里XXX::XX的具体内部设计使用了经典的RAII,下文再表。