2019独角兽企业重金招聘Python工程师标准>>>

当你构建和销毁一个对象的时候,构造函数与析构函数通常是成对出现的,如果调用构造函数的次数多于析构函数,那么多半有内存(或其它资源)泄漏了。

struct Resource
{Resource() { puts("create"); } //构造函数~Resource() { puts("destroy"); }  //析构函数
};

C++11 支持匿名对象

struct Test
{int a;int b;
};int main()
{Test { 10, 20 }; //生成一个匿名对象, a = 10, b = 20
}

我们构造一个 Resource 的结构体,然后用这个结构体构造匿名对象

struct User
{Resource r1;Resource r2;
};

构造两个函数,一个正常创建一个 Resource 对象,一个在创建过程中抛出一个异常

Resource make_1() { return Resource(); }
Resource make_2() { throw std::runtime_error("failed"); }

现在测试,在匿名对象中抛出一个异常,检测 create 与 destroy 是否成对出现

//prog.cc#include <cstdio>
#include <stdexcept>struct Resource
{Resource() { puts("create"); }~Resource() { puts("destroy"); }
};//正常创建对象
Resource make_1() { return Resource(); }
//抛出异常
Resource make_2() { throw std::runtime_error("failed"); }struct User
{Resource r1;Resource r2;
};int main()
{try { User {make_1(), make_2()}; }catch (...) {}
}//command: g++ -std=c++11 prog.cc -o obj
//output:  create

可见,发生了内存泄漏。如果把 main 函数换成下列代码,则能不会发生内存泄漏

int main()
{try { User u{make_1(), make_2()}; }//非匿名对象,使用集合初始化器初始化catch (...) {}
}

分析原因:

非匿名对象情况下的 异常处理代码:

L18:movl    36(%esp), %eaxmovl    %eax, 24(%esp)leal    94(%esp), %eaxmovl    %eax, %ecxcall    __ZN8ResourceD1Ev //注意这里,调用了一次 Resource 的析构函数movl    24(%esp), %eaxmovl    %eax, (%esp)call    ___cxa_begin_catch //异常捕获开始movl    $-1, 32(%esp)call    ___cxa_end_catch  //异常捕获结束jmp     L17

匿名对象的 异常处理代码:

L18:movl    36(%esp), %eaxmovl    %eax, (%esp)call    ___cxa_begin_catch  //异常处理开始movl    $-1, 32(%esp)call    ___cxa_end_catch    //异常处理结束jmp     L17

通过对比可以发现,GCC不会在异常处理机制中调用匿名对象的析构函数,而对于具名对象,通过静态检查,查看 throw 前有多少个对象,则在异常处理部分加上对应个数的析构函数,比如:

struct Test
{Object a;Object b;Object c;Object d;
}try{Test t { new Test(), new Test(), bug here, new Test() };
}catch(...){}

此时,异常处理部分中会添加 a, b 两个对象的析构函数。

Author: tiger Bin · L

Reference: https://akrzemi1.wordpress.com/2017/04/27/a-serious-bug-in-gcc/

转载于:https://my.oschina.net/tigerBin/blog/889434

GCC的缺陷,由匿名对象引起的内存泄漏相关推荐

  1. android编译非静态内部类,Android 非静态内部类/匿名类引起的内存泄漏

    一.概述 让我们先来回顾一下android内存泄漏的相关概念: 内存溢出:android系统会给每个安卓程序分配一定的内存,当程序所使用的内存超过最大值就会造成内存溢出,就是常说的OOM 内存泄漏:简 ...

  2. netty ByteBuf对象池和内存泄漏检测实现走读

    该文已重写,请移步: https://blog.csdn.net/weixin_40318210/article/details/108970208 https://blog.csdn.net/wei ...

  3. 在使用SPSite对象时容易发生内存泄漏

    如题所说,在使用SPSite对象时容易内存泄漏!造成内存泄漏的原因是没有正确地关闭SPSite对象,请大家Review一下代码,及时修正! 项目中,对系统进行压力测试时,出现了大量的异常信息,类似如下 ...

  4. java 匿名list,java创造匿名对象的两种方法

    在java中有时候需要一些匿名对象的使用.可能有些小伙伴拿还不会创造,其实我们在学习一些方法时都或多或少的接触过.本篇所要讲到的创造匿名对象总结了两种方法,分别是静态工具方法和Lambda表达式,我们 ...

  5. C++之匿名对象与析构函数的关系

    #include <iostream>using namespace std;class Location{ public:Location(int xx = 0, int yy = 0) ...

  6. Java中的匿名对象

    匿名对象 创建对象的标准格式: 类名称 对象名 = new 类名称(); 匿名对象就是只有右边的对象,没有左边的名字和赋值运算符. new 类名称(); 匿名对象 注意事项:匿名对象只能使用唯一的一次 ...

  7. java中抽象类的匿名子类和匿名对象

    package com.atguigu.com;/** **抽象类的匿名子类和匿名对象*** * * */public class PeronTest {public static void main ...

  8. Java基础super关键字、final关键字、static关键字、匿名对象整理

    super关键字 10.1子父类中构造方法的调用 public class Test { public static void main(String[] args) { new Zi(); } } ...

  9. 匿名对象和object的转换

    参考http://www.2cto.com/kf/201207/139227.html 有时候经常用到需要把一个匿名对象存入session或List<object>或其他容器中,可是取出来 ...

最新文章

  1. Installation error: INSTALL_FAILED_INSUFFICIENT_STORAGE
  2. ML之二分类预测:以岩石水雷数据集(RockMine)为例从0到1深入理解科学预测之分类问题的思路框架(特征工程详细步骤(特征分析与特征处理)+分类模型设计)
  3. ArrayList方法源码
  4. 前端之 JavaScript 常用数据类型和操作
  5. POJ 2287 - Tian Ji -- The Horse Racing(贪心)
  6. Thread之四:java线程返回结果的方法
  7. VS2013 VC2013 VC 远程调试 配置步骤
  8. AXI仿真之AXI Chip2Chip
  9. ixp协议服务器,ipx协议中的“内部网络号”是什么意思?
  10. 单片机c51语言实训总结,单片机实训报告
  11. 如何打造有战斗力的团队
  12. ������ʾ����
  13. C语言关于输入某天日期求是本年第几天(计算天数)
  14. 科普大佬说 | 智能仿生机器鱼
  15. 脚注交叉引用序号不一样_学会Word交叉引用,再也不用一个一个改编号了
  16. 信息系统项目管理师---第九章 项目人力资源管理历年考题
  17. c语言 数组 随机数 初始化
  18. 【RabbitMQ】消息应答--ack机制
  19. 小昭的早晨——微信小程序开发伊始
  20. 利用免费代理ip网站建立自己IP数据库

热门文章

  1. Tom邮箱注册机|注册辅助工具!!!
  2. 根据表格中的数据长度自动调整表格宽度DBGrid
  3. 如果彩虹QQ算非法外挂,那么运行在windows上的非微软开发的程序算什么?
  4. js 中的 __proto__
  5. ES6新特性_ES6扩展运算符的介绍---JavaScript_ECMAScript_ES6-ES11新特性工作笔记013
  6. SentinelResource注解配置下_客户自定义限流处理_削峰填谷_流量控制_速率控制_服务熔断_服务降级---微服务升级_SpringCloud Alibaba工作笔记0047
  7. MyCat分布式数据库集群架构工作笔记0009---Mycat主--从复制配置上
  8. 正则表达式学习笔记005--脱字符和美元符的认识与应用
  9. java面试准备之---Struts2体系知识点,系统复习,struts2原理,ognl,el支持.---随时更新
  10. VS2015配置jsoncpp详解