问题聚焦:
    使用了资源管理对象(如智能指针),就一定是安全的吗?显然不是。
    资源泄露发生可能在于,在“资源被创建”和“资源被转换为资源管理对象”两个时间点之间有可能发生异常干扰。

看下面这个例子:
//函数说明
int priority();    //揭示处理程序的优先权
void processWidget(std::tr1::shared_ptr<Widget> pw, int priority); // 用来在某动态分配所得的Widget上进行某些带有优先权的处理
// 这里对动态分配得来的Widget运用智能指针
// 现在考虑调用processWidget
processWidget(new Widget, priority()); // 显然编译是不通过的,原因是类型不匹配。 // 如果像下面这样调用即可
processWidget(std::tr1::shared_prt<Widget>(new Widget), priority()); // 编译通过

然而令人惊讶的是,上述正确的调用方法,却可能发生资源泄露。
分析:
调用processWidget之前,编译器需要做三件事:
  • 调用priority
  • 执行“new Widget”
  • 调用tr1:shared_ptr构造函数
问题在于:C++编译器是以什么样的次序完成这些事情的呢?
答案是不确定的。
可以确定的是:“new Widget”一定执行于tr1::shared_ptr构造函数被调用之前。
但是对priority的调用则可以排在第一第二或第三的位置。
当priority的调用排在第二的位置时,执行次序如下:
  1. 执行“new Widget”
  2. 调用priority
  3. 调用tr1:shared_ptr构造函数
潜在的问题:如果第二步发生异常,new Widget返回的指针将会遗失。(其实为什么会遗失,这个问题有待验证)
所以,资源泄露发生可能在于,在“资源被创建”和“资源被转换为资源管理对象”两个时间点之间有可能发生异常干扰。

解决的方案:
使用分离语句
std::tr1::shared_ptr<Widget> pw(new Widget);
processWidget(pw, priority());
依据在于:编译器对于“跨越语句的各项操作”没有重新排列的自由。

小结:
以独立语句将newed对象存储于智能指针内,如果不这样做,一旦异常被抛出,有可能导致难以察觉的资源泄漏。
参考资料:
《Effective C++ 3rd》

Effective C++(17) 以独立语句将newed对象置入智能指针的更多相关文章

  1. Effective C++ 条款17 以独立语句将newed对象置入智能指针

      对于函数: int priority(); void processWidget(std::tr1::  shared_ptr<Widget> pw,int priority); 调用 ...

  2. [Effective C++ --017]以独立语句将newed对象置入智能指针

    这一节也比较简单,先假设我们有如下的函数: int foo(); void memFoo(shared_ptr<T> pw, int foo); 现在假设我们要调用memFoo函数: me ...

  3. 条款17:以独立语句将newed对象置入智能指针(Store newed objects in smart pointers in standalone statements)

    NOTE: 1.以独立语句将newed对象存储于智能指针内.如果不这样做,一旦异常被抛出,有可能导致难以察觉的资源泄漏.

  4. Effective C++ -----条款17:以独立语句将newed对象置入智能指针

    以独立语句将newed对象存储于(置入)智能指针内.如果不这样做,一旦异常被抛出,有可能导致难以察觉的资源泄露.

  5. 条款17:以独立语句将newed对象置入智能指针

    请牢记: 以独立语句将newed对象存储于(置入)智能指针内.如果不这样做,一旦异常被跑出来,有可能导致难以察觉的资源泄露. 假设有个函数用来处理程序的优先权,另一个函数用来在某动态分配所得的Widg ...

  6. 《Effective C++》——条款17:以独立语句将newed对象置入智能指针

    假设有如下两个函数: int priority(); void processWidget(std::tr1::shared_ptr<Widget>pw, int priority); 对 ...

  7. 【17】以独立语句将newed对象置入智能指针

    1.为什么? 考虑下面的情况:方法声明为void processWidget(shared_ptr<Widget> pw,int priority). 调用方法 processWidget ...

  8. [EffectiveC++]item17:以独立语句将newed对象置入智能指针

    Store newed objects in smart pointers in standalone statements

  9. 以独立的语句将new对象置入智能指针

    以独立的语句将newed对象置入智能指针: processWidget(std::tr1::share_ptr<Widget>(new Widget) , priority()); 我们在 ...

随机推荐

  1. Log4net 日志

    Log4net 日志使用介绍 概述 Log4net 有三个主要组件:loggers,appenders 和 layouts.这三个组件一起工作使得开发者能够根据信息类型和等级(Level)记录信息,以 ...

  2. Angular内置指令

    记录一下工作中使用到的一些AngularJS内置指令 内置指令:所有的内置指令的前缀都为ng,不建议自定义指令使用该前缀,以免冲突 1. ng-model 使用ng-model实现双向绑定,通过表单的 ...

  3. thinkphp学习笔记9—自动加载

    原文:thinkphp学习笔记9-自动加载 1.命名空间自动加载 在3.2版本中不需要手动加载类库文件,可以很方便的完成自动加载. 系统可以根据类的命名空间自动定位到类库文件,例如定义了一个类Org\ ...

  4. Python challenge 3 - urllib &amp; re

    第三个主题地址:http://www.pythonchallenge.com/pc/def/ocr.html Hint1:recognize the characters. maybe they ar ...

  5. C++ 在dynamic_cast&lt;&gt;用法

    /*这是从网上断开的试样.主要是关于 dynamic_cast<> 用法.*/ /* 行动:对象指向一个基类(或参考)cast一个指向派生类,dynamic_cast将基于一个基类指针确实 ...

  6. 至尊快速,国产语言RPP 1.83强势来袭

    以下是 R++的性能測试数据:(奔腾 1.86GHZ,測试 3 次取平均值) 执行效率: R++的内部结构和 C++大致同样,所以理论上 R++能够达到和 C++一样的执行速度,眼下 R++已开启汇编 ...

  7. Python - 安全替换字符串模板(safe_substitute) 详细解释

    安全替换字符串模板(safe_substitute) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/27057339 字 ...

  8. Web监控工具

    .Rabbitmq的使用及Web监控工具使用   一.文档资料        1.官方网站:http://www.rabbitmq.com/        2.安装教程:http://www.rabb ...

  9. 关于C#操作INI文件的总结

    原文:关于C#操作INI文件的总结   INI文件其实是一种具有特定结构的文本文件,它的构成分为三部分,结构如下: [Section1]key 1 = value2key 1 = value2--[S ...

  10. 清理收缩VMware虚拟机MacOS系统的vmdk文件大小

    屌丝行和差的主要标准,尽管持续性眼贪婪mbp.但是,从另一方面限制患有米,只是在虚拟机中播放MacOS.(我不会告诉你我的笔记本i5+120SSD+500HHD+12G内存,跑MacOS虚拟机一点不卡 ...