为什么会陷入死循环
来源:互联网 发布:网络连接错误代码651 编辑:程序博客网 时间:2024/04/29 09:59
看似简单的一段程序如下:
int main()
{
int i,j[8];
for(i=0;i<=8;i++)
j[i]=0;
return 0;
}
在UNIX/Linux平台下,gcc编译运行会陷入死循环.
因为变量 i 和数组 j[8]是保存在栈中,默认是由高地址向低地址方向存储. 输出变量地址可以发现: i 存储位置在0xbfd90dec,j[0]、j[1]...j[7]在内存的地址分别是0xbfdab05c、0xbfdab060,...0xbfdab078. 如下所示:
高地址 <--------------------------------------->低地址
i,j[7],j[6],j[5],j[4],j[3],j[2],j[1],j[0]
如果在int i,j[8]后面再定义变量int c,那么c就存放在j[0]的往低方向的下一个地址0xbfdab058 .
int main()
{
int i,j[8];
for(i=0;i<=8;i++)
j[i]=0;
return 0;
}
在UNIX/Linux平台下,gcc编译运行会陷入死循环.
因为变量 i 和数组 j[8]是保存在栈中,默认是由高地址向低地址方向存储. 输出变量地址可以发现: i 存储位置在0xbfd90dec,j[0]、j[1]...j[7]在内存的地址分别是0xbfdab05c、0xbfdab060,...0xbfdab078. 如下所示:
高地址 <--------------------------------------->低地址
i,j[7],j[6],j[5],j[4],j[3],j[2],j[1],j[0]
如果在int i,j[8]后面再定义变量int c,那么c就存放在j[0]的往低方向的下一个地址0xbfdab058 .
现在不难理解这段程序为什么会出现死循环了。j[8]的位置就是变量i所在的位置。这样当i=8时的j[i]=0语句,实际上就是将i的值置为0,然后 i 又从0到8循环一直下去. 如果将原句改为int j[8],i; 就不会出现死循环,而仅仅是一个段越界错误.
另一个程序:
#include <stdio.h>
int main()
{
int i;
char c;
for(i=0;i<5;i++)
{
scanf("%d",&c);
printf("i=%d ",i);
}
printf("/n");
}
编译后运行
[foxman@local~]#./a.out
0 (输入0)
i=0 (输出 i 值)
1
i=0
2
i=0
3
i=0
4
i=0
...
这样一直循环下去。
问题在于,c被声明为char类型,而不是int类型。当程序要求scanf读入一个整数时,应该传递给它一个指向整数的指针。而程序中scanf得到的却是一个指向字符的指针,scanf函数并不能分辨这种情况,只能将这个指向字符的指针作为指向整数的指针而接受,并且在指针指向的位置存储一个整数。因为整数所占的存储空间要大于字符所占的存储空间,所以c附近的内存会被覆盖.
由上面分析,i 和 c 是由高地址到低地址存储在栈中,这样在c所在位置尝试存储一个4字节变量,会占用比c高的3个字节(覆盖掉 i 字节的低3位),即使 i 总是为零,一直循环下去.
如果每次输入Ctrl+D作为字符终止符不存储int到c处,那么就会输出正常i=0..4了.- 为什么会陷入死循环
- 为什么会陷入死循环
- fclose 陷入死循环
- hashmap陷入get方法陷入死循环
- vfork为什么会出现死循环
- 程序陷入死循环问题的解决
- Java HashMap多线程下为什么会死循环?
- 并发的HashMap为什么会引起死循环?
- 并发的HashMap为什么会引起死循环
- 为什么是死循环
- while(true){ i++;} 如何不会陷入死循环
- 做了个软连接,结果,陷入了死循环
- SVN CleanUp失败陷入死循环的解决办法
- tomcat启动 扫描hbm.xml映射文件 陷入死循环
- SVN Update Commit Cleanup 报错 陷入死循环解决方案
- Bootstrap table 刷新回调陷入死循环
- ssm项目一直报错,陷入死循环,解决办法
- 为什么Web 设计会“死”?
- vsftpd使用root登录
- STL map常用操作简介
- 编译错误syntax error : missing ';' before 'type'原因探寻
- String、StringBulider和StringBuffer
- 打包WebApp
- 为什么会陷入死循环
- c#调用非托管C++生成的dll
- 数据库设计规范(命名规范)
- 嵌入式组态软件系统的研究
- JSTL 1.0入门: 表达式语言
- 总结一下Meta的用法及robot.txt的讲解
- html保留标签截字
- SQL Server数据库完整迁移
- js获取页面宽和高