C++中以独立语句将new对象置入智能指针

简介: C++中以独立语句将new对象置入智能指针

1.问题的引入


假设现在有个函数priority()来处理程序的优先级,另一个函数用来在某动态分配的Widget对象上进行某些带有优先权的处理。


1class Widget{
2    // ...
3};
4
5int priority();
6
7void processWidget(std::shared_ptr<Widget> pw, int priority);


现在,有下面的语句调用函数processWidget(),如下所示:


1processWidget(new Widget, priority());


上面的语句调用必然会导致编译器报错,这是由于std::shared_ptr构造函数需要一个原始指针,但该构造函数是一个explicit显式构造函数,无法进行隐式转换。下面调用方式将new Widget原始指针转换为processWidget()所要求的std::shared_ptr。,如下所示:


1processWidget(std::shared_ptr<Widget>(new Widget), priority());


重点来了:即使经过上面一系列的骚操作(即使用对象管理式资源),上面的调用也可能发生内存泄漏


2.内存泄漏发生的原因及解决方法



先看看编译器的工作原理。编译器在生成对processWidget()函数的调用之前,必须先解析其中的参数processWidget()函数接收两个参数,分别是智能指针的构造函数和整型的函数priority()。在调用智能指针构造函数之前,编译器必须先解析其中的new Widget语句。因此,解析该函数的参数分为三步:  

   (1).调用priority();

   (2).执行new Widget;
   (3).调用std::shared_ptr构造函数;


C+编译器以什么样的固定顺序去完成上面的这些事情呢?答案是未知。这和其他语言如Java和C#不同,这两种语言总是以固定的顺序完成函数参数的解析。但是,在C++中可以确定步骤(2)一定先于步骤(3)执行,因为new Widget还要被传递作为std::shared_ptr构造函数的一个实参。然而,对于priority()的调用可以在步骤(1)、步骤(2)、步骤(3)执行。假设编译器选择以步骤(2)执行它,最终的操作次序如下:  

(1).执行new Widget;    (2).调用priority();    (3).调用std::shared_ptr构造函数


但是,如果priority()函数抛出了异常呢?那么从new语句动态分配的资源在到达智能指针构造函数之前就已经泄露了。解决方法:使用一个单独的语句来创建智能指针对象。


1std::shared_ptr<Widget> pw(new Widget);  // 放在单独的语句中
2processWidget(pw, priority());   // 不会泄露资源


编译器是逐语句编译的,通过使用一个单独的语句来构造智能指针对象,编译器就不会随意改动解析顺序,保证了生成的机器代码顺序是异常安全的,以及这样的代码写出来也更加美观。


3.总结



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

相关文章
|
4天前
|
C++ 数据格式
LabVIEW传递接收C/C++DLL指针
LabVIEW传递接收C/C++DLL指针
10 1
|
2天前
|
C++ 编译器
|
4天前
|
存储 安全 程序员
C++:智能指针
C++:智能指针
19 5
|
5天前
|
存储 安全 C++
深入理解C++中的指针与引用
深入理解C++中的指针与引用
8 0
|
6天前
|
Java C++ Python
【C++从练气到飞升】06---重识类和对象(二)
【C++从练气到飞升】06---重识类和对象(二)
|
6天前
|
编译器 C++
【C++从练气到飞升】06---重识类和对象(一)
【C++从练气到飞升】06---重识类和对象(一)
|
6天前
|
存储 编译器 C语言
【C++从练气到飞升】02---初识类与对象
【C++从练气到飞升】02---初识类与对象
|
6天前
|
算法 C++
【C++入门到精通】智能指针 shared_ptr循环引用 | weak_ptr 简介及C++模拟实现 [ C++入门 ]
【C++入门到精通】智能指针 shared_ptr循环引用 | weak_ptr 简介及C++模拟实现 [ C++入门 ]
10 0
|
6天前
|
安全 算法 数据安全/隐私保护
【C++入门到精通】智能指针 shared_ptr 简介及C++模拟实现 [ C++入门 ]
【C++入门到精通】智能指针 shared_ptr 简介及C++模拟实现 [ C++入门 ]
11 0
|
6天前
|
存储 算法 安全
【C++入门到精通】智能指针 auto_ptr、unique_ptr简介及C++模拟实现 [ C++入门 ]
【C++入门到精通】智能指针 auto_ptr、unique_ptr简介及C++模拟实现 [ C++入门 ]
11 0