技术分享| C++ 程序内存泄漏检测方法

2018-11-30 16:37:28

      程序中通常包含着静态内存和栈内存。静态内存用来保存局部static对象、类static数据成员以及定义在任何函数之外的变量(全局变量)。栈内存用来保存定义在函数内的非static对象。分配在静态或栈内存中的对象由编译器自动创建和销毁。对于栈对象,仅在定义的程序块运行时才存在,程序退出,栈对象也随即销毁;static对象和全局对象则是在程序结束时销毁。除了静态内存和栈内存,程序还拥有一块内存池,这部分也就是称为堆。在使用堆空间是就需要使用动态内存分配。

内存泄漏:是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。对于服务器程序及需要长时间运行的程序来说,检测和解决内存泄漏是程序员必备的技能。接下来,西安中软卓越的老师分享几个C++程序内存泄漏检测方法,希望对大家有所帮助。

技术分享(Z).jpg

1.   内存泄漏出现的情况总结

首先总结一下c++在语法上的错误使用导致的内存泄漏,所以在编写程序时,就尽量避免错误的编写。

1  正确的使用newdelete运算符,需要注意的是newdelete要匹配使用,对于初学者这种情况是最常出现的。一般出错的地方像如下的例子,在指针p的值被另一个函数所使用。

    char * FunA()

    {

             char *p = new char;

             return p

    }

    void FunErrorB()

    {

             char *b = FunA()

             //忘记delete p       

    }

 

2      释放对象数组时,没有使用delete[]。如例子所示:

    Void FunErrorA()

    {

             Char *p = new char[10];

             Delete p;

    }

 3 双指针释放错误,存在指针释放的遗漏。如例子正确的释放一个双指针

    Void FunRightA()

    {

             Char **p = new char*[10];

             For(int i=0;i<10;i++)

             {

                       p[i] = new char[10];

             }

             If(p!=nullptr)

             {

                       For(int i=0;i<10;i++)

                       {        Delete []p[i];

                                p[i] = nullptr;

                       }

                       Delete []p;

                       p = nullptr;

             }

    }

 (4)缺少拷贝构造函数。在类里存在成员变量是指针时,在进行赋值=运算和按值传参时,必须重载拷贝构造函数,重新实现其指针拷贝的部分.

(5)没有将基类的析构函数定义为虚函数。当基类指针指向子类对象时,如果基类的析构函数不是virtual,那么子类的析构函数将不会被调用,子类的资源没有正确是释放,因此造成内存泄露。

6)调用库存在内存泄漏。在使用由个人包装或者未完全测试的库时,要确定此库对本程序不存在性能的影响。
     c++
提供了auto_ptrunique_ptrshared_ptrweak_ptr这几种智能指针(auto_ptrC++98提供的解决方案,C+11已将将其摒弃,并提供了另外两种解决方案。)在此西安中软卓越的老师只介绍后三个智能指针:

1shared_ptr共享的智能指针:

shared_ptr使用引用计数,每一个shared_ptr的拷贝都指向相同的内存。在最后一个shared_ptr析构的时候,内存才会被释放。

注意事项:

1.不要用一个原始指针初始化多个shared_ptr

2.不要再函数实参中创建shared_ptr,在调用函数之前先定义以及初始化它。

3.不要将this指针作为shared_ptr返回出来。

4.要避免循环引用。

2unique_ptr独占的智能指针:

<1>Unique_ptr是一个独占的智能指针,他不允许其他的智能指针共享其内部的指针,不允许通过赋值将一个unique_ptr赋值给另外一个 unique_ptr

<2>unique_ptr不允许复制,但可以通过函数返回给其他的unique_ptr,还可以通过std::move来转移到其他的unique_ptr,这样它本身就不再 拥有原来指针的所有权了。

<3>如果希望只有一个智能指针管理资源或管理数组就用unique_ptr,如果希望多个智能指针管理同一个资源就用shared_ptr

(3)weak_ptr弱引用的智能指针:

弱引用的智能指针weak_ptr是用来监视shared_ptr的,不会使引用计数加一,它不管理shared_ptr内部的指针,主要是为了监视shared_ptr的生命 周期,更像是shared_ptr的一个助手。 weak_ptr没有重载运算符*->,因为它不共享指针,不能操作资源,主要是为了通过shared_ptr获得资源的监测权,它的构造不会增加引用计数,它的析构不会减少引用计数,纯粹只是作为一个旁观者来监视shared_ptr中关连的资源是否存在。 weak_ptr还可以用来返回this指针和解决循环引用的问题。

作为一名开发人员,技术是立身的根本,是拴马桩的尊严;对于一个做教育机构,口碑如水是生命之源,是长盛不衰的根本。13年历经风雨依然昂首前行,未来的西安中软卓越同样会恪守初心,以技术立身,培养IT精英,捍卫教育本质。

本文由中软卓越(西安)汇集整理,转载请注明作者及出处。

如需学习java、UI设计、软件测试、Python、大数据、嵌入式、Linxu云计算,请点击咨询,加入我们让你的未来不再迷茫。

关于我们

【中软卓越】-中软国际旗下高端教育品牌,是中软国际有限公司投资的大型人才服务机构,是中软国际人才战略的核心组成部分之一,承担集团发展过程中人才储备和培养的任务;专注IT培训37年,国内高端IT培训品牌,教育部指定官方IT人才培训机构。专注java培训、UI设计培训、软件测试培训、Python培训、大数据培训、嵌入式培训、Linxu云计算培训等培训课程。217家合作院校,880家合作企业,真实项目实战,素质拓展,职业规划。零首付,100%保障就业,先就业,后付款。

最牛逼的毕业学员入职名企享受高薪就业。880家合作企业,年培育学员人数逾6000人,毕业学员就职于中软国际、百度、腾讯、阿里巴巴、IBM、华为科技、中兴通讯、软通动力等知名企业。

还有什么疑问?我们全面为你解答!为您提供一对一专人服务,请点击下方咨询

  • 卓越资讯
  • 猜你想看
  • 常见问题

    Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。[详细课程]

    软件开发是根据用户要求建造出软件系统或者系统中的软件部分的过程;软件开发是一项包括需求捕捉、需求分析、设计、实现和测试的系统工程。[详细课程]

    软件测试是在规定的条件下对程序进行操作,以发现程序错误,衡量软件质量,并对其是否能满足设计要求进行评估的过程。[详细课程]

    Python是一种面向对象的解释型计算机程序设计语言,语法简洁清晰,特色之一是强制用空白符作为语句缩进,它常被昵称为胶水语言,能够把用其他语言制作的各种模块。[详细课程]

    UI设计分为实体UI和虚拟UI,互联网说的UI设计是虚拟UI,一般是指对软件的人机交互、操作逻辑、界面美观的整体设计。[详细课程]

    大数据,又称巨量资料,指的是所涉及的数据资料量规模巨大到无法通过人脑甚至主流软件工具,在合理时间内达到撷取、管理、处理、并整理成为帮助企业经营决策更积极目的的资讯。[详细课程]

    云计算是一种按使用量付费的模式,这种模式提供可用的、便捷的、按需的网络访问, 进入可配置的计算资源共享池(资源包括网络,服务器,存储,应用软件,服务),这些资源能够被快速提供,只需投入很少的管理工作,或与服务供应商进行很少的交互。[详细课程]

    西安市长安北路8号高速大厦三楼

    电话:029-61876930