数组越界
闲话不多说,先上一段代码:
int main(){
int i = 0;
int arr[3] = {0};
for(;i<=3;i++){
arr[i] = 0;
printf("hello world\n");
}
return 0;
}
看到没,数组大小为3,arr[0],arr[1],arr[2],而我们的for循环结束条件错写为i<=3,出现了arr[3]访问越界。在C语言中,我跑起来无限打印“hello world”。数组越界这种事很可怕啊,我们都知道很多计算机病毒都利用代码中的数组越界访问非法地址的漏洞来攻击系统,而在C语言中数组越界又是一种未决行为,编译器不会做任何处理,所以在写代码的过程中还是要很注意啊。当然,在java中就直接抛出异常了。那么怎么就数组越界就造成了死循环呢?
先分析这张图:
如果堆栈是向下增长,也就是从高地址向低地址增长,那么在任务刚开始创建后,堆栈是空的。如图中例子,栈顶在为TaskStk[0][511],栈底为在TaskStk[0][0]。压栈后,在原来栈顶位置插入数据0x0012ff78,然后栈顶位置向低地址方向移4个字节,指向TaskStk[0][510]。----此段摘抄以便理解。
在vc6.0中堆栈是向下增长的,也就是从高地址指向低地址的,那么i在高地址出,arr地址稍低一点,数组内部地址又是按顺序增长的,所以存储如下:
arr[3] i (高)
arr[2]
arr[1]
arr[0] (低)
越界之后,arr[3]占用了i原本的位置,i的值又变成了0,不断循环下去,造成死循环问题。
不过,有的高级编译器在数组和之间的存储位置上开辟了一块区间,避免占用,从而一定程度上解决死循环问题。
为了看一下真的是堆栈向下增长和数组内部位置按顺序增长,写了一段程序理解一下:
当然,我这个就是之间开辟了区间的。