首页 » PHP教程 » php句柄怎么设置技巧_聊聊 C 中的几种智能指针 上

php句柄怎么设置技巧_聊聊 C 中的几种智能指针 上

访客 2024-11-17 0

扫一扫用手机浏览

文章目录 [+]

void test() {int i = new int(10);i = 10;}int main() {test();}

这段代码由于用了 new 而忘了 delete,导致在 nt heap 上分配的 i 随着栈地址的回收而成了一块孤悬外洋的内存占用,以是改动后的代码如下:

void test() {int i = new int(10);i = 10;delete i;}int main() {test();}

但这种写法比较麻烦,智者千虑必有一失落,总会有忘却加 delete 的时候,那怎么办呢? 大家该当知道内存自动管理有两种手段。

php句柄怎么设置技巧_聊聊 C 中的几种智能指针 上

引用计数

代表作有 Python,PHP,还有 windows 的句柄管理。

php句柄怎么设置技巧_聊聊 C 中的几种智能指针 上
(图片来自网络侵删)
引用跟踪

代表作有 C#,JAVA 等一众工程化措辞。

由于 引用计数 实现比较大略,紧张便是记录下工具的引用次数,次数为 0 则开释,以是可完备借助 类的布局函数析构函数 和 栈的自动回收特性 弄一个大略的 引用计数 ,对应着如下四个关键词。

auto_ptrshared_ptrunique_ptrweak_ptr

接下来我们逐个聊一聊。

二:关键词解析1. auto_ptr

这是 C++ 最早涌现一个的 大略引用计数法,参考代码如下:

void test() {auto_ptr<int> ptr = auto_ptr<int>(new int(10));}int main() {test();}

接下来看下汇编代码:

auto_ptr<int> ptr = auto_ptr<int>(new int(10));...00771D26 call std::auto_ptr<int>::auto_ptr<int> (07710FAh) 00771D2B lea ecx,[ebp-0D8h] 00771D31 call std::auto_ptr<int>::~auto_ptr<int> (0771159h)

可以看到,它分别调用了 布局函数 和 析构函数,接下来找下 auto_ptr 这两个函数的源码。

class auto_ptr {private:_Ty _Myptr; // the wrapped object pointerpublic:auto_ptr(auto_ptr_ref<_Ty> _Right) noexcept {_Ty _Ptr = _Right._Ref;_Right._Ref = nullptr; // release old_Myptr = _Ptr; // reset this}~auto_ptr() noexcept {delete _Myptr;}}

源码一看就明白了,在布局函数中,将 new int 的地址塞给了内部的 _Myptr 指针,在析构函数中对 _Myptr 进行 delete ,真好,这样就不用整天担心有没有加 delete 啦。

值得把稳的是,现在 C++ 不推举这个了,而是建议利用新增的:shared_ptr,unique_ptr,weak_ptr, 怎么说呢? auto_ptr 有一个不好处理的问题,便是现实开拓中会涌现这么个场景,多个 ptr 指向同一个 引用,如下图:

2. auto_ptr 多引用问题办法1:

定义三个 ptr,然后包装同一个 new int 地址,参考代码如下:

void test() {int i = new int(10);auto_ptr<int> ptr1(i);auto_ptr<int> ptr2(i);auto_ptr<int> ptr3(i);}

这种写法有没有问题呢? 肯定有问题啦,还记得 auto_ptr 的析构是 delete 吗? 对同一块内存多次 delete 会抛非常的,如下图所示:

办法2:

既然定义三个有问题, 那就用赋值运算符= 让 ptr1,ptr2,ptr3 指向同一个地址是不是就可以啦? 参考代码如下:

void test() {int i = new int(10);auto_ptr<int> ptr1(i);auto_ptr<int> ptr2 = ptr1;auto_ptr<int> ptr3 = ptr2;}int main() {test();}

那这段代码有没有问题呢? 有没有问题得要看 = 运算符是如何重写的,扒一下源码看看。

template <class _Other>auto_ptr& operator=(auto_ptr<_Other>& _Right) noexcept {reset(_Right.release());return this;}_Ty release() noexcept {_Ty _Tmp = _Myptr;_Myptr = nullptr;return _Tmp;}

从源码看有一个很恶心的点,他会将 _Right 下的 _Myptr 设为 nullptr,也便是说此时的 ptr1 报废了,言外之意便是后续再访问 ptr1 会抛 访问违例。

哈哈,C++里面的专业术语叫 掌握权转移。

好了,本篇就说这么多吧,下一篇聊聊新增的这些关键词,看看如何将 auto_ptr 更合理的分权。

标签:

相关文章

介绍白点控制之路,从原理到方法

白点,作为生活中常见的现象,无处不在。对于如何控制白点,许多人却感到困惑。本文将从原理出发,探讨白点的控制方法,并结合实际案例,为...

PHP教程 2025-01-03 阅读1 评论0

介绍直播王者,如何开启你的电竞直播之旅

随着电竞产业的蓬勃发展,越来越多的年轻人投身于电竞直播行业。王者荣耀作为一款备受欢迎的MOBA手游,吸引了大量玩家和观众。如何开启...

PHP教程 2025-01-03 阅读1 评论0