unique_ptr的成员函数release到底会不会释放内存空间

bear234 2015-11-29 01:10:20
我正在看《c++ primer》第五版中文版,关于unique_ptr。

在第418页,书上说:

unique_ptr的release()只是放弃对指针的控制权,返回指针,并将自己置为空。

换句话说,release并不会调用delete。所以我们可以这样:

unique_ptr<int> up(new int(10));
unique_ptr<int> up2(up.release());

而在第425页是这样写的:
unique_ptr<int[]> up(new int[10]());
up.release(); // 自动delete[]销毁其指针


这里我就不明白了,怎么release又自动调用delete[]了?前面说release不会delete而只是放弃对指针的控制权啊?


是我理解有问题还是书上写错了?
...全文
1195 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
hgz 2017-04-19
  • 打赏
  • 举报
回复
http://en.cppreference.com/w/cpp/memory/unique_ptr/release http://en.cppreference.com/w/cpp/memory/unique_ptr/reset 这两个例子可以很好的解释你的问题
jiht594 2016-12-08
  • 打赏
  • 举报
回复
Releases ownership of its stored pointer, by returning its value and replacing it with a null pointer. This call does not destroy the managed object, but the unique_ptr object is released from the responsability of deleting the object. Some other entity must take responsibility for deleting the object at some point. To force the destruction of the object pointed, either use member function reset or perform an assignment operation on it.
ri_aje 2016-12-08
  • 打赏
  • 举报
回复
release 不会调用 delete 的。可以 unique_ptr<自定义类> 看析构函数。
qq_20084041 2016-12-07
  • 打赏
  • 举报
回复
书上写错了,你可以把unique_ptr的deleter重载,再分别调用release和reset,可以看到只有后者真的执行了deleter。
paschen 版主 2015-11-29
  • 打赏
  • 举报
回复
Use release to take over ownership of the raw pointer stored by the unique_ptr. The caller is responsible for deletion of the returned pointer. The unique-ptr is set to the empty default-constructed state. You can assign another pointer of compatible type to the unique_ptr after the call to release. https://msdn.microsoft.com/en-us/library/ee475597.aspx
fefe82 2015-11-29
  • 打赏
  • 举报
回复
release 只是释放控制权,不会释放内存。 释放内存可以用 reset(nullptr);
C++智能指针:auto_ptr详解 指针,相信⼤家并不陌⽣。⽆论是我们在进⾏查看内存还是在修改字符串,我们都⽤到指针。 最常见的情况则是我们使⽤malloc或者new申请到了⼀块内存,然后⽤⼀个指针来保存起来。我们都知道有内存的申请那就必须要对它进⾏ 释放的处理,否则造成最严重的后果——内存泄漏。⼀个或者两个申请的内存我们或许忘记去释放,但是如果成千上万⾏代码,你还 能记得住哪个释放了哪个没有释放吗? ⽽智能指针就是为了解决这个问题⽽产⽣的。最开始智能指针是在boost库中的,随着时间发展现在已经成为了C11的特性。(虽然我们本 篇要介绍的最基础的auto_ptr在C++11中已经被unique_ptr替代了。。) 智能指针的基本原理 智能指针其实是⼀个类,可以通过将普通指针作为参数传⼊智能指针的构造函数实现绑定。只不过通过运算符重载让它"假装"是⼀个指 针,也可以进⾏解引⽤等操作。既然智能指针是⼀个类,对象都存在于栈上,那么创建出来的对象在出作⽤域的时候(函数或者程序结束) ⾃⼰消亡,所以在这个类中的析构函数中写上delete就可以完成智能的内存回收。 Auto_ptr详解 使⽤时,需要包含头⽂件:memory。 auto_ptr,作为智能指针的始祖,能基本实现我们所期望的功能。⽽且设计简单源码易懂,虽然缺陷众多,但作为了解智能指针的研究对象 还是⼗分合适的。 ⾸先我们先来写⼀个测试类⽤于分析。 #include #include using namespace std; class Test { public: Test(int param = 0) //调⽤时,可以指定是第⼏个对象。默认第0个 { num = param; cout << "Simple:" << num << endl; } ~Test() //析构时指出第⼏个对象被析构。 { cout << "~Simple:" << num << endl; } void PrintSomething() //输出附加的字符串⽅法。 { cout << "PrintSomething:" << info_extend.c_str() << endl; } int num; //代表这个对象的序号。 string info_extend; //附加的字符串。 }; 接下来,我们通过⼏个测试函数来实验⼀下auto_ptr的基本功能,再来了解⼀下它的弊端。 I.Auto_ptr的基本功能 的基本功能 void TestAutoPtr1() { auto_ptr my_auto (new Test(1)); //绑定⼀个Test类的新建对象 if(my_auto.get()) //get函数⽤来显式返回它拥有的对象指针,此处判⾮空 { my_auto->PrintSomething(); my_auto.get()->info_extend = "Addition"; //对类内成员进⾏操作 my_auto->PrintSomething(); //看是否成功操作 (*my_auto).info_extend += " other"; //实验解引⽤操作 mt_auto->PrintSomething(); } } 运⾏结果: 我们可以看到在绑定时输出Simple:1,之后也能正常实现Test类中的功能,同时my_auto可以通过get⽅法进⾏裸指针赋值以及使⽤*进⾏ 解引⽤操作,与普通指针⽆异。最后函数结束后,在调⽤析构函数的同时auto_ptr的析构函数也将Test类的对象delete掉,我加⼊的内存泄 漏探测⼯具也显⽰No memory leaks detected(没有检查测到内存泄漏). II.Auto_ptr的弊端 的弊端1 void TestAutoPtr2() { auto_ptr my_auto1 (new Test(1)); if(my_auto1.get()) { (*my_auto1).info_extend = "Test"; //先赋予⼀个初始值作为区别两个指针的标志 auto_ptr my_auto2; my_auto2 = my_auto1; my_auto2->PrintSomething(); //打印发现成功转移 my_auto1->PringSomething(); //崩溃 } } 在这个程序的最后⼀步崩溃,罪魁祸⾸就是my_auto2 = my_auto1语句。 autp_ptr对赋值运算符重载的实现是reset(Myptr.release()),即reset和release函数的组合。release释放所有权,reset则是⽤于接受
c++11智能指针解析——揭开底层⾯纱,完整理解智能指针 昨天跟同事⼩⼩的研究了下关于不同平台下的字节对齐问题,起因是遇到了⼀个坑,vs上没有问题,在安卓上却崩溃了。找了半天后发现是 c++字节补齐问题,期间包括使⽤#pragma pack(1)来限定字节对齐⽅式等各种条件,也是把我们搞的七晕⼋素,总算是进⼀步了解了c++对 象结构以及编译器的操作(有机的话也补充下字节对齐的理解)。进⽽想到了智能指针,稍微了解下。第⼀次接触智能指针,天知道⼤学 期间⾃⼰有多不努⼒,很多知识点都得留到现在来补齐,所以还是做做笔记吧。 简断截说:c++的⼊门坑点⼤家都是有⽬共睹的,⽆⾮就是指针的理解不深导致⼀些野指针,内存泄露等问题,所以就不赘述。智能指针正 好能够弥补这些问题,因为它本质是存放在栈的模板对象,只是在栈内部包了⼀层指针。⽽栈在其⽣命周期结束时,其中的指针指向的堆内 存也⾃然被释放了。因⽽实现了智能管理的效果,不需要考虑内存问题了,其实有点类似某种单例写法,程序运⾏结束,也不⽤考虑单例对 象内存问题。 本次讨论:c++11之前的auto_ptr; c++11新加的unique_ptr, shared_ptr以及weak_ptr。 头⽂件:#include 1.auto_ptr auto_ptr是我第⼀个看的智能指针,也是标准库⾥的智能指针,有许多缺陷。 ⾸先看下结构: 从图中可以看书也是⼀个模板,使⽤⽅法⼤致类似于vector模板。如下: class Base1 { //__int64 ss; //public: bool dd; int m_itest; public: virtual void func(){ cout << "test successed" << endl; } };//先写⼀个测试类 main函数如下: int _tmain(int argc, _TCHAR* argv[]) { auto_ptr base1(new Base1);//可理解为先声明⼀个名为base1的Base1类型智能指针,然后再base1⾥⾯管理new Base1 if (base1.get())//get是智能指针的函数,返回当前当前智能指针对象,即⽤以判断是否为空 { base1->func(); } return 0; } 正常⽤法是这样,然⽽我们可以再仔细翻看下底层: 从上图可以看出,该智能指针成员函数也与vector相似,很容易得出 1、base1.get():返回当前指针对象; 2、base1.release():清空当前智能指针对象,并返回类型指针。所以假如我们要正常删除,那么需要这样: Base1*base2 = base1.release(); delete base2; 很⿇烦对不对,没关系,还有第三个函数呢 3、base1.reset():从图中可看出,是重置智能指针,即把内存删除,且智能指针指向空,但类型不变,所以可以这样安全便捷地删除: base1.reset(); 然⽽继续看,还有⼀个问题: auto_ptr还重载了等号操作符,由图可知意思是把赋值智能指针的内存交给被赋值智能指针,即如下意思: auto_ptr base2; base2 = base1;//将base1的控制权转交给base2,且base1清空了 base2->func(); 因此这样就有些问题,控制权可以随便转换,但是只有⼀个在⽤,⽤起来受到诸多限制,所以有了下⾯的智能指针。 介绍之前先上⼀张别⼈的表格,来源:,这是c++11中的智能指针与boost库中的⽐较,原本boost就是为完善auto_ptr搞得这些,现在 c++11有了,也就不需要再⽤咯。 2.unique_ptr C++11引⼊了许多便捷的功能,其中也包括这个,在⽤之前我们可以先看下底层: 可以清楚的看到,unique_ptr中的拷贝构造和赋值操作符delete了,所以也就意味着,他和auto_ptr有区别,控制权唯⼀,不能随意转换。⽤法都差不 多: unique_ptr base1(new Base1); unique_ptr base2;//但是不能⽤拷贝构造和等号赋值把base1赋值给base2了 但是如果想切换控制权的话也不是没有办法,我们可以看到还有个这样的函数: 要理解这两个函数,⾸先要理解c++11引⼊的move和forward;⽽要理解move和forward得先理解左值和右值概念。所以还是讲全⼀点吧(已经了解的 就直接跳过可以): 补充知识点(其实可以直接看我下⼀篇更⽅便理解:): 1、左值与右值: 左值指的是既能够出现在等号左边也能出现在等号右边的变量(或表达式),右值指的则是只
学习并掌握C++2.0(11+14+17+20)的新特性,学习线程及线程池的应用 ---------------------------------------------------给小白学员的3年学习路径及计划技术方面分三块:1.纯开发技术方向2.音视频流媒体专业方向3.项目实战---------------------------------------------------1.纯开发技术方向(1) C++必须要过硬(至少学10本经典好书)(2) 系统级编程(Windows、Linux),必须特别熟练系统API,灵活运用(3) 框架与工具(Qt、MFC):必须精通其中一种。(4) 架构与设计模式:需要提升一个高度,不再是简单的编码,而是思维模式。(5) 驱动级别(如果有兴趣,可以深入到驱动级:包括Windows、Linux)(6) 最好学习点Java+Html+javascript等WEB技术。2.音视频流媒体专业方向(1) 音视频流媒体基础理论:   必须认真学,否则看代码就是看天书(2) 编解码方向:精通h.264,h.265(hevc), 包括理论和各个开源库(ffmpeg,libx264,libx265,...)。(3) 直播方向:  精通各种直播协议(rtsp,rtmp,hls,http-flv,...), 钻研各个开源库(live555,darwin,srs,zlmediakit,crtmpserver,...)(4) 视频监控:  理论+开源库(onvif+281818)(EasyMonitor、iSpy、ZoneMinder(web)、...) 3.项目实战(1) Qt项目:  至少要亲手练习10个实战项目(网络服务器、多线程、数据库、图像处理、多人聊天、等等)(2)音视频项目:包括编解码、视频监控、直播等各个方向,都需要亲手实战项目,包括视频服务器、后台管理系统、前端播放器(多端)---------------------------------------------------  第1章 C++11新特性 41). nullptr关键字与新语法 42). auto和decltype类型推导 6 auto讲解 6 auto示例 7 decltype 83). for区间迭代 94). 初始化列表 105). 模板增强 11外部模板 11类型别名模板 12默认模板参数 126). 构造函数 13委托构造 13继承构造 147). Lambda 表达式 158). 新增容器 20std::array 20std::forward_list 21无序容器 22元组 std::tuple 239). 正则表达式 2610). 语言级线程支持 28多线程库简介 2811). 右值引用和move语义 31右值引用和move语义 32转移左值 3412). constexpr 35第2章 C++14新特性 36Lambda 函数 36类型推导 37返回值类型推导(Return type deduction) 37泛型lambda 39[[弃用的]]  [[deprecated]]属性 40二进制数字和数字分隔符 41第3章 C++17新特性 42安装GCC10.2 42安装msys2-x86_64-20200720 42更新镜像 42更新软件库 43安装 MinGW64 等必要的软件 43环境变量Path 43编译命令 43constexpr 44typename 45折叠表达式 47结构化绑定 48条件分支语句初始化 49聚合初始化 50嵌套命名空间 52lambda表达式捕获*this的值 53改写/继承构造函数 54用auto作为非类型模板参数 55__has_include 56fallthrough 57nodiscard 57maybe_unused 58第4章 C++20新特性 59编译命令 59concept 59typename 60explicit 61constinit 62位域变量的默认成员初始化 62指定初始化 63基于范围的for循环初始化 64放宽基于范围的for循环,新增自定义范围方法 65嵌套内联命名空间 66允许用圆括弧的值进行聚合初始化 67unicode字符串字面量 68允许转换成未知边界的数组 68likely和unlikely 69第5章 C++2.0(11/14/17/20)总结与分析 705.1 C语言与C++ 715.2 语言可用性的强化 725.2.1 常量 725.2.2 变量及其初始化 735.2.3 类型推导 745.2.4 控制流 765.2.5 模板 775.2.6 面向对象 815.3 语言运行期的强化 835.3.1 Lambda 表达式 835.3.2 右值引用 865.4 容器 885.4.1 线性容器 885.4.2 无序容器 895.4.3 元组 895.5 智能指针与内存管理 905.5.1 RAII 与引用计数 905.5.2 std::shared_ptr 905.5.3 std::unique_ptr 915.5.4 std::weak_ptr 91第6章 C++2.0多线程原理与实战 93什么是并发 93并发的方式 93为什么使用并发 95线程简介 96创建线程的三种方式 971. 通过函数 972.通过类对象创建线程 993.通过lambda表达式创建线程 101thread线程的使用 101互斥量与临界区 105期物Future 111条件变量 112原子操作 114内存模型 118第7章 C++2.0线程池原理与实战 120线程与线程池的基本原理 1201)、线程 1202)、线程的生命周期 1213)、什么是单线程和多线程 1214)、线程池 1225)、四种常见的线程池 123线程池的架构与流程 123线程池代码实战 125    

64,653

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧