![](/style/images/good.png)
![](/style/images/bad.png)
从C++ std::shared_ptr 原理来看看栈溢出的危害
source link: http://satanwoo.github.io/2019/01/26/shared-ptr/?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
C++ std::shared_ptr 实现原理
上周五排查了一个由于 XXX模块
操作疏忽导致栈越界引发的 我的模块
的智能指针Crash问题,因此稍微研究了一下,以作参考:
shared_ptr共享被管理对象,同一时刻可以有多个shared_ptr拥有对象的所有权,当最后一个shared_ptr对象销毁时,被管理对象自动销毁
shared_ptr 实现
简单来说, shared_ptr
实现包含了两部分,
- 一个指向堆上创建的对象的裸指针
- 一个指向内部隐藏的、共享的管理对象。
第一部分没什么好说的,第二部分是需要关注的重点:
-
use_count
,当前这个堆上对象被多少对象引用了,简单来说就是引用计数。 -
weak_count
,这个管理对象被多少个智能指针共享了,简单来说就是管理对象
的引用计数。
不同指针创建的对同一个堆上对象的智能管理,并不共享管理对象,因此存在 double free
的可能性
_shared_ptr
直接包含的裸指针是为了实现一般指针的->,*等操作,通过 __shared_count
间接包含的指针是为了管理对象的生命周期,回收相关资源。
换句话说, __shared_count
内部的 use_count
主要用来标记被管理对象的生命周期, weak_count
主要用来标记管理对象的生命周期。
问题原因
了解了原理,可以看出 std::share_ptr
本身的 _M_ptr
指向了堆上通过 new
创建的对象。但是其自身这个 _M_ptr
却会如果在不当操作上,被修改,比如栈越界操作,就会被破坏,导致产生对非法对象的访问:
int i = 5; NSLog(@"i address is %p", &i); XXX::XX df = XXX::XX::buildDataFrame(); NSLog(@"sp0 address is %p", &df); int a[1] = {1}; NSLog(@"k address is %p", a); for (int i = 0; i < 10; i++) { a[i] = i; } NSLog(@"haha");
上述这段代码就会引发问题,这里 XXX::XX
的具体内部设计使用了经典的RAII,下文再表。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK