同样的一段代码

#include<stdio.h>
int main(int argc, char **argv)
{
  int i;
  int a[5];
  for(i=0;i<6;i++)
    a[i]=0;
  printf("hello word");
  return 0;
}

在linux和windows上运行的结果是不同的。在windows上由于数组越界导致for进入死循环而没有输出,但在linux上却是有输出的,难道是Linux没有发生数组越界吗?并不是这样的。
先来看一下这段代码的栈数据i和数组a在windows上的内存分配图
这里写图片描述
从这张内存图中数组最后一个元素的地址和i的地址是连续的,于是当数组越界后会覆盖掉i地址上原来的数据,于是for就进如了死循环,程序无输出。
但是上述代码运行在linux系统(Fedora 23,Ubuntu 15.10 )上是会有输出,但是同样的也越界了于是分别查看了i和a[4]的地址:
这里写图片描述
用gdb的输出可以看到i的地址和a[4]的地址间有一段空余(此处为12字节的空闲),于是他的栈内存应该是这样的
这里写图片描述
由上图可以看到在linux上有输出不是应为它没有越界,而是它越界不够厉害,地址还没越到i的地址上去,所以i保留了它原来的数据,for会终止。
这里写图片描述
在许多次尝后发现数组和非数组数据之间总会有一段栈内存的空余来防止越界造成的不良后果。或许这就是linux 为了防止越界产生的不可预知错误所做的一点补救吧。

Logo

更多推荐