我们先看一个linux下的C代码,分析一下运行结果:
1 int main(int argc, char* argv[]) {
2 int i = 0;
3 int arr[3] = {0};
4 for(; i<=3; i++) {
5 arr[i] = 0;
6 printf("hello world\n");
7 }
8 return 0;
9 }
显然,由于数组越界导致行为未知?
其实,行为虽然非法,但并不是未知或者因为非法访问而退出。
我们知道,在 C 语言中,只要不是访问受限的内存,所有的内存空间都是可以自由访问的。根据数组寻址方式(线性连续),a[3] 也会被定位到某块不属于数组的内存地址上,而这个地址正好是存储变量 i 的内存地址,那么 a[3]=0 就相当于 i=0,所以就会导致代码无限循环。
看到这里,应该还有很多疑问,但是还是请先思考一下。
我们再进一步,函数体内的局部变量存在栈上,且是连续压栈。在Linux进程的内存布局中,栈区在高地址空间,从高向低增长。变量 i 和 arr 在相邻地址,且 i 比 arr 的地址大,所以 arr 越界正好访问到 i。当然,前提是 i 和 arr 元素同类型,否则那段代码仍是未决行为。
看到这里,应该大体的原因已经说清楚了,那么如果想了解的更加深入,我给大家推荐一个链接:GCC 中的编译器堆栈保护技术
最后,给大家再留一个思考:如果 arr[3] 变成 arr[5],结果是否还会无限循环呢?
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。