C++ 内存泄露和内存越界
内存泄露:分配了内存而没有释放,逐渐耗尽内存资源,导致系统崩溃
内存越界: 打个比方 就是你有一个500ml的水瓶,然后你倒在瓶里的水大于500ml 那个多余的就会流出来...
1. 原理分析
经常有些新C++程序员问:C++的类的成员个数是不是有限制,为什么我加一个变量后程序就死了?或者说:是不是成员变量的顺序很重要,为什么我两个成员变量顺序换一换程序就不行了?凡此种种之怪现象,往往都是内存访问越界所致。
何谓内存访问越界,简单的说,你向系统申请了一块内存,在使用这块内存的时候,超出了你申请的范围。例如,你明明申请的是100字节的空间,但是你由于某种原因写入了120字节,这就是内存访问越界。内存访问越界的后果是:你的写入破坏了本不属于你的空间。
下面是一个简单的例子:
int a;
char b[16]="abcd";
int c;
a = 1;
c = 2;
printf("a=%d,c=%d/n", a,c);
memset(b, 0,32); //注意这里访问越界了,你只有16字节空间,却修改了32字节
printf("a=%d,c=%d/n", a,c);
你可以看出,在memset前后,两个printf语句打印出来的值并不一样,因为memset越界后修改了a或者c的值(由于不同编译器对变量在空间中顺序的安排可能有不同策略,因此我用两个变量,希望能抓到越界信息。对于VC,debug模式下系统添加了很多填充字节,你可能需要增加越界的数量才能看到效果)
2. 为什么增加一个变量后程序就崩溃了?
增加一个变量后,内存中变量的布局也发生了变化。如果一个内存越界破坏了一个不含指针的结构,程序虽然逻辑不对,但是不至于崩溃。但是如果增加变量后,内存访问越界破坏了一个指针,则会导致程序崩溃。
例如:
nt a;
char b[128];
//bool c;
char* d=new char[128];
int e;
b[136] = '/0';
b[137] = '/0';
b[138] = '/0';
b[139] = '/0';
strcpy(d, "haha");
注意, b访问越界了8个字节位置处的4个字节。如果没有c,那么越界破坏了e变量,不会导致程序崩溃。但是加上c之后,破坏的变量可能就是d了,由于指针被破坏后,一旦访问就是内存访问违例,导致程序崩溃。
这也解释了为什么交换顺序会导致程序崩溃。如果上面情况没有变量c,你交换e和d,结构也是类似的,程序也一样要崩溃。
3. 为什么有些情况越界了程序也没错?
这主要是说这个话的人对什么是“错”没有正确的认识。程序不是只有崩溃了才是错!你破坏了别的变量,那个变量总有被使用的时候,尽管那个变量不会导致诸如程序崩溃、报警之类的严重错误,但是其计算结果必然是错误的。你说“程序没错”,是因为你根本没有发现错误而已。这种情况甚至比程序直接崩溃还要恶劣,因为程序一旦崩溃你肯定会去查,可以在导致真正严重的问题之前就把问题解决了。而如果计算错误隐藏到很晚,你的损失就可能很大了。(例如,一颗卫星上天了,你才发现一台仪器由于软件故障无法测量真正的数据,那得多少损失?)
4. 如何解决内存访问越界问题?
老实说没有好的方法。遇到这种问题,首先你得找到哪里有内存访问越界,而一个比较麻烦得问题在于,出现错误得地方往往不是真正内存越界得地方。对于内存访问越界,往往需要进行仔细得代码走查、单步跟踪并观察变量以及在调试环境得帮助下对变量进行写入跟踪(如VC6就有一旦变量被修改就break得机制)。
更重要得是,程序员要养成良好的编程习惯,在修改每个数组时一定要对这个数组有多少空间有清醒的认识,否则一旦出错,找到原因是很痛苦的事情。
C++ 内存泄露和内存越界的更多相关文章
- net 内存泄露和内存溢出
一直以来都对内存泄露和内存溢出理解的不是很深刻.在网上看到了几篇文章,于是整理了一下自己对内存泄露和内存溢出的理解. 一.概念 内存溢出:指程序在运行的过程中,程序对内存的需求超过了超过了计算机分配给 ...
- java内存泄露与内存溢出
内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory: 内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空 ...
- C++内存机制中内存溢出、内存泄露、内存越界和栈溢出的区别和联系
当我们在用C++做底层驱动的时候,经常会遇到内存不足的警告,究其原因,往往是因为内存出现溢出,泄露或者越界等原因.那么他们之间有什么联系吗? 内存溢出(out of memory) 是指程序在申请内存 ...
- 如何避免JavaScript的内存泄露及内存管理技巧
发表于谷歌WebPerf(伦敦WebPerf集团),2014年8月26日. 高效的JavaScript Web应用必须流畅,快速.与用户交互的任何应用程序,都需要考虑如何确保内存有效使用,因为如果 ...
- Android为TV端助力 转载:内存泄露与内存溢出的区别
内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory:比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出. ...
- Android 的内存泄露和内存限制
转载自 https://blog.csdn.net/goodlixueyong/article/details/40716779 https://blog.csdn.net/vshuang/artic ...
- Android之内存泄露、内存溢出、内存抖动分析
内存 JAVA是在JVM所虚拟出的内存环境中运行的,内存分为三个区:堆.栈和方法区.栈(stack):是简单的数据结构,程序运行时系统自动分配,使用完毕后自动释放.优点:速度快.堆(heap) ...
- java中内存泄露和内存溢出
内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory:比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出. ...
- Java:内存泄露和内存溢出
1. 内存溢出 (Memory Overflow) 是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory:比如申请了一个integer,但给它存了long才能存下的数,那就 ...
随机推荐
- Bilateral Multi-Perspective Matching for Natural Language Sentences---读书笔记
自然语言句子的双向.多角度匹配,是来自IBM 2017 年的一篇文章.代码github地址:https://github.com/zhiguowang/BiMPM 摘要 这篇论文主要 ...
- Linux 基本权限管理
1.linux权限表示: -rw-r--r-- (一共10位): 第一位:表示文件类型: 常用的三种文件类型:- 表示一般文件,d 表示目录,l 表示软链接文件: 后九位:每三位为一组: rwx r- ...
- Mysql错误--Table 'mysql.servers' doesn't exist.
问题: 今天在初始化数据库的时候,在配置文件里加了"--skip grant tables",登陆进去之后,发现无法修改root密码,报这个错误. Table 'mysql.s ...
- PTA(Basic Level)1039.到底买不买
小红想买些珠子做一串自己喜欢的珠串.卖珠子的摊主有很多串五颜六色的珠串,但是不肯把任何一串拆散了卖.于是小红要你帮忙判断一下,某串珠子里是否包含了全部自己想要的珠子?如果是,那么告诉她有多少多余的珠子 ...
- java学习(东软睿道)2019-09-07(预课html基础)《随堂笔记》
1. 文件名称.html 2. 后缀表示文件类型.txt .doc .ppt 3. 标签<html> <head> <body> 显示内容 <font siz ...
- 解决Eclipse中文文档注释错位-处女座的悲哀!
1.右键打开eclips属性 2.选择兼容性为win8,然后打开Eclipse即可解决 作者:醉烟 出处:https://www.cnblogs.com/WangLei2018/ 本文版权归作者 ...
- SQLite进阶-14.子查询
目录 子查询 SELECT语句中的子查询 INSERT语句中的子查询 UPDATE语句中的子查询 DELETE语句中的子查询 子查询 子查询或内部查询或嵌套查询是在另一个SQLite查询内嵌入在WHE ...
- Vufuria入门 1 图片识别和选择
Vufutia中的图片识别功能,底层主要是识别特征点来实现的.特征点,即那些棱角分明的点.尖锐的而不是圆滑的.对比度大的而不是小的. *** 步骤: 进入vofuria官网,登录,点击develop. ...
- 9.ssh登录慢
修改方式:使用root权限修改ssh的配置文件,vim /etc/ssh/sshd_config增加一行记录:UseDNS no修改GSSAPIAuthentication参数为 no,默认是yesP ...
- 利用神器BTrace 追踪线上 Spring Boot应用运行时信息
概述 生产环境中的服务可能会出现各种问题,但总不能让服务下线来专门排查错误,这时候最好有一些手段来获取程序运行时信息,比如 接口方法参数/返回值.外部调用情况 以及 函数执行时间等信息以便定位问题.传 ...