大家好,欢迎来到IT知识分享网。
案例
首先我们来看一段代码
#include<stdio.h>
int main()
{
int i = 0;
int arr[] = {
1,2,3,4,5,6,7,8,9,10 };
for (i = 0; i <= 12; i++)
{
arr[i] = 0;
printf("hello\n");
}
return 0;
}
大家觉得这段代码的运行结果时什么呢? 相信会有人说数组越界,也会有人认为应该打印
出13个hello,那么真实的结果是什么样的呢? 我们来调试看一下。
首先当 i 从 0 到 9 时,如我们预料一样,arr[0]到arr[9]被置成了0
接着, arr[10],arr[11]也相继被置成了0,但i =12时,我们可以惊奇的发现,i 和arr[12]的值是一样的,难道 i 和arr[12]是占用的相同的内存空间吗? 有读者可能会觉得arr[12]还没有被初始化,那么12有可能只是一个随机值罢了。
那么,我们打开调试里的内存窗口看一看
由此我们可以知道 i 和arr[12] 占用的内存空间就是一样的,接下来我们将arr[12]改成了0,也就是将循环变量 i 改成了0,这样就会无限循环的打印 hello
案例分析
那么为什么 i 和arr[12]的空间是一样的呢?
i 和arr数组都是局部变量,被放在内存的栈区
栈区内存的使用习惯是: 先使用高地址处的空间,再使用低地址处的空间。因此 i 被放置在了相对于数组来说较高的地址处。
数组随着下标的增长,地址是由低到高变化的。
i 和arr数组大致的内存分布情况如下图所示, 图中一个格子代表4个字节
所以,当数组适当越界得情况下,就可能导致越界访问到循环变量i,改变i的值就可能导致死循环。
相信有人会怀疑为什么一定i和arr数组之间就恰好各了两个空格(也就是8个字节)呢?这难道不是巧合吗?
确实,编译器不同,i和arr数组之间所差的字节不同,而在VS编译器下就差8个字节,但是在Linux x86_64 gcc环境下,它们所差的就是4个字节(也就是一个格子)。
该案例也提醒我们以后在写代码时,一定要注意数组越界的情况。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/21020.html