C++内存泄漏的几种情况
1. 在类的构造函数和析构函数中没有匹配的调用new和delete函数
两种情况下会出现这种内存泄露:一是在堆里创建了对象占用了内存,但是没有显示地释放对象占用的内存;二是在类的构造函数中动态的分配了内存,但是在析构函数中没有释放内存或者没有正确的释放内存
2. 没有正确地清除嵌套的对象指针
3. 在释放对象数组时在delete中没有使用方括号
方括号是告诉编译器这个指针指向的是一个对象数组,同时也告诉编译器正确的对象地址值病调用对象的析构函数,如果没有方括号,那么这个指针就被默认为只指向一个对象,对象数组中的其他对象的析构函数就不会被调用,结果造成了内存泄露。如果在方括号中间放了一个比对象数组大小还大的数字,那么编译器就会调用无效对象(内存溢出)的析构函数,会造成堆的奔溃。如果方括号中间的数字值比对象数组的大小小的话,编译器就不能调用足够多个析构函数,结果会造成内存泄露。
释放单个对象、单个基本数据类型的变量或者是基本数据类型的数组不需要大小参数,释放定义了析构函数的对象数组才需要大小参数。
4. 指向对象的指针数组不等同于对象数组
对象数组是指:数组中存放的是对象,只需要delete []p,即可调用对象数组中的每个对象的析构函数释放空间
指向对象的指针数组是指:数组中存放的是指向对象的指针,不仅要释放每个对象的空间,还要释放每个指针的空间,delete []p只是释放了每个指针,但是并没有释放对象的空间,正确的做法,是通过一个循环,将每个对象释放了,然后再把指针释放了
5. 缺少拷贝构造函数
两次释放相同的内存是一种错误的做法,同时可能会造成堆的奔溃。
按值传递会调用(拷贝)构造函数,引用传递不会调用。
在C++中,如果没有定义拷贝构造函数,那么编译器就会调用默认的拷贝构造函数,会逐个成员拷贝的方式来复制数据成员,如果是以逐个成员拷贝的方式来复制指针被定义为将一个变量的地址赋给另一个变量。这种隐式的指针复制结果就是两个对象拥有指向同一个动态分配的内存空间的指针。当释放第一个对象的时候,它的析构函数就会释放与该对象有关的动态分配的内存空间。而释放第二个对象的时候,它的析构函数会释放相同的内存,这样是错误的。
所以,如果一个类里面有指针成员变量,要么必须显示的写拷贝构造函数和重载赋值运算符,要么禁用拷贝构造函数和重载赋值运算符
6. 缺少重载赋值运算符
这种问题跟上述问题类似,也是逐个成员拷贝的方式复制对象,如果这个类的大小是可变的,那么结果就是造成内存泄露,如下图:
7. 关于nonmodifying运算符重载的常见迷思
a. 返回栈上对象的引用或者指针(也即返回局部对象的引用或者指针)。导致最后返回的是一个空引用或者空指针,因此变成野指针
b. 返回内部静态对象的引用。
c. 返回一个泄露内存的动态分配的对象。导致内存泄露,并且无法回收
解决这一类问题的办法是重载运算符函数的返回值不是类型的引用,二应该是类型的返回值,即不是 int&而是int
8. 没有将基类的析构函数定义为虚函数
当基类指针指向子类对象时,如果基类的析构函数不是virtual,那么子类的析构函数将不会被调用,子类的资源没有正确是释放,因此造成内存泄露
野指针:指向被释放的或者访问受限内存的指针。
造成野指针的原因:
- 指针变量没有被初始化(如果值不定,可以初始化为NULL)
- 指针被free或者delete后,没有置为NULL, free和delete只是把指针所指向的内存给释放掉,并没有把指针本身干掉,此时指针指向的是“垃圾”内存。释放后的指针应该被置为NULL.
- 指针操作超越了变量的作用范围,比如返回指向栈内存的指针就是野指针。
C++内存泄漏的几种情况的更多相关文章
- Js内存泄漏的几种情况
想解决内存泄露问题,必须知道什么是内存泄露,什么情况下出现内存泄露,才能在遇到问题时,逐个排除.这里只讨论那些不经意间的内存泄露. 一.什么是内存泄露 内存泄露是指一块被分配的内存既不能使用,又不能回 ...
- java内存泄漏的几种情况
转载于http://blog.csdn.net/wtt945482445/article/details/52483944 Java 内存分配策略 Java 程序运行时的内存分配策略有三种,分别是静态 ...
- C++中内存泄漏的几种情况
1. 在类的构造函数和析构函数中没有匹配的调用new和delete函数 两种情况下会出现这种内存泄露:一是在堆里创建了对象占用了内存,但是没有显示地释放对象占用的内存:二是在类的构造函数中动态的分配了 ...
- js造成内存泄漏的几种情况
1.介绍js的垃圾回收机制 js的垃圾回收机制就是为了防止内存泄漏的,内存泄漏的含义就是当已经不需要某块内存时这块内存还存在着,垃圾回收机制就是间歇的不定期的寻找到不再使用的变量,并释放掉它们所指向的 ...
- Java内存泄漏的几种可能
Java内存泄漏引起的原因: 内存泄漏是指无用对象(不再使用的对象)持续占有内存或无用对象的内存得不到及时释放,从而造成内存空间的浪费称为内存泄漏. 长生命周期的对象持有短生命周期对象的引用就很可能发 ...
- js内存泄露的几种情况
想解决内存泄露问题,必须知道什么是内存泄露,什么情况下出现内存泄露,才能在遇到问题时,逐个排除.这里只讨论那些不经意间的内存泄露. 一.什么是内存泄露 内存泄露是指一块被分配的内存既不能使用,又不能回 ...
- 【转载】Android内存泄漏的8种可能
Java是垃圾回收语言的一种,其优点是开发者无需特意管理内存分配,降低了应用由于局部故障(segmentation fault)导致崩溃,同时防止未释放的内存把堆栈(heap)挤爆的可能,所以写出来的 ...
- java 内存泄露的几种情况
内存泄漏定义(memory leak):一个不再被程序使用的对象或变量还在内存中占有存储空间. 一次内存泄漏似乎不会有大的影响,但内存泄漏堆积后的后果就是内存溢出.内存溢出 out of memory ...
- Tomcat内存溢出的三种情况及解决办法分析
Tomcat内存溢出的原因 在生产环境中tomcat内存设置不好很容易出现内存溢出.造成内存溢出是不一样的,当然处理方式也不一样. 这里根据平时遇到的情况和相关资料进行一个总结.常见的一般会有下面三种 ...
随机推荐
- sqlalchemy链接数据库
from sqlalchemy import create_engine HOSTNAME = '127.0.0.1' PORT = 3306 DATABASE = 'first_sqlalchemy ...
- JAVA第四周总结
Java实验报告二 第一题 写一个名为Rectangle的类表示矩形.其属性包括宽width.高height和颜色color,width和height都是double型的,而color则是String ...
- SQL的DDL和DML
DDL:数据定义语言,定义库.表结构用的DML:数据操作语言,增.删.改.查DCL:数据控制语言,权限.事务等控制语句 (一)DDL1.操作数据库的语句(1)查看当前DBMS中的所有数据库show d ...
- 3. Linux的shell编程
Shell 是一个用 C 语言编写的程序, 通过 Shell 用户可以访问操作系统内核服务.它类似于 DOS 下的 command 和后来的 cmd.exe.Shell 既是一种命令语言,又是一种程序 ...
- 小白学习django第四站-关联数据库
使用mysql连接django首先要配置好相关环境 首先在setting.py配置数据库信息(需要现在mysql中创建一个数据库) 在setting.py那个目录的__init__.py文件中写入 之 ...
- 实现一台Linux电脑连接另一台Linux(SSH实现linux之间的免密码登陆)
怎么实现一台Linux电脑连接另一台Linux电脑? 首先查看是否安装ssh服务:systemctl status sshd.service 启动服务:systemctl start sshd.ser ...
- 前端之BOM,DOM
前戏 到目前为止,我们已经学过了JavaScript的一些简单的语法.但是这些简单的语法,并没有和浏览器有任何交互. 也就是我们还不能制作一些我们经常看到的网页的一些交互,我们需要继续学习BOM和DO ...
- tomcat启动报ClassNotFound
排除本来就缺少该类的原因,经过自己经验和网上查的资料,解决方式如下: jar包冲突(关闭其他项目) eclipse的java版本不对,点击项目,右键properties在project facets, ...
- java中的包注意事项
1:需要导入包的三个地方 a:需要导入第三方的jar包中的类或接口 b:需要导入除了java.lang包的其他包中的类(jdk中的类) c:需要导入自己写的不同包的类 2:引入包的三种方式 a:imp ...
- docker在mac下安装及配置阿里云镜像加速
安装 brew cask install docker 配置 关于阿里云加速地址,下面会有详细说明 阿里云官方镜像加速 官方文档:https://help.aliyun.com/document_de ...