内存访问越界(转)

原创 2011年01月08日 13:10:00

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. 为什么增加一个变量后程序就崩溃了?
增加一个变量后,内存中变量的布局也发生了变化。如果一个内存越界破坏了一个不含指针的结构,程序虽然逻辑不对,但是不至于崩溃。但是如果增加变量后,内存访问越界破坏了一个指针,则会导致程序崩溃。

例如:

int 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得机制)。

更重要得是,程序员要养成良好的编程习惯,在修改每个数组时一定要对这个数组有多少空间有清醒的认识,否则一旦出错,找到原因是很痛苦的事情。

 

相关文章推荐

GFlags 检查内存越界、野指针等作用的工具使用

Normal 0 7.8 磅 0 2 false false false Microsof...

程序猿之---C语言细节6(数组参数、数组越界、编译器内存分配)

主要内容:数组参数、数组越界、编译器内存分配

有关 内存溢出、泄露、越界、缓冲区溢出、栈溢出

前言:借鉴学习+自我理解。若是有不恰当的地方,希望大家可以不吝赐教。 ----------------------------------------------------------------...

解释:内存溢出、内存泄露、内存越界、缓冲区溢出、栈溢出

内存溢出就是你要求分配的内存超出了系统能给你的,系统不能满足 需求,于是产生溢出。 ========================================================...

内存溢出、内存泄露、内存越界、缓冲区溢出、栈溢出

内存溢出 就是你要求分配的内存超出了系统能给你的,系统不能满足需求,于是产生溢出。 内存泄漏 是指你向系统申请分配内存进行使用(new),可是使用完了以后却不归还(delete),结...
  • cch1024
  • cch1024
  • 2015年12月10日 14:56
  • 411

解释:内存溢出、内存泄露、内存越界、缓冲区溢出、栈溢

内存溢出就是你要求分配的内存超出了系统能给你的,系统不能满足需求,于是产生溢出。一个盘子用尽各种方法只能装4 个果子,你装了5个,结果掉倒地上不能吃了。这就是溢出!比方说栈,栈满时再做进栈必定产生空间...

【腾讯优测干货分享】越用越卡为哪般——如何降低App的待机内存(一)

最近小优听说,隔壁的**腾讯TMQ团队出了一本新书——《移动App性能评测与优化》**,便借阅了一本来读,读完感觉写得确实很赞。这本书体系化地介绍了移动应用性能评测与优化的方方面面,如内存,电量,流畅...

直接内存访问(DMA)【转】

1. 什么是DMA 直接内存访问是一种硬件机制,它允许外围设备和主内存之间直接传输它们的I/O...

一道有趣的数组越界、循环问题

初来乍到,也是第一次写博客,能与诸君共同学习交流也是极好的。 现在就贴上我们的源代码: #include int main() { int i, a[10]; for (i = 0; i ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:内存访问越界(转)
举报原因:
原因补充:

(最多只允许输入30个字)