QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 1093|回复: 13

这个……为什么是无限循环?

[复制链接]
发表于 2004-8-16 15:44:19 | 显示全部楼层 |阅读模式
  

[code:1]#include <stdio.h>

void loop();
void addr();

int main(){
             addr();
             loop();
}

long *p;

void loop(){
             long i,j;
             j=0;
             for (i=0;i<10;i++){
                    (*p)--;
                    j++;
              }
}

void addr(){
              long k;
              k=0;
              p=&k;
}
[/code:1]

还有这个

[code:1]

#include <stdio.h>

int main(){
             int i;
             int a[10];
             for(i=0;i<=10;++i) a[i]=0;
             exit(0);
}[/code:1]
发表于 2004-8-16 16:15:04 | 显示全部楼层
第一个:在代码看来只有一个指针的赋值有问题,在我本地编译运行确实是无限循环,在loop函数中加了个printf来看输出,i和*p的值恒为0,把k定义成全局变量就一切OK了。
第二个:我在本地编译运行没有问题啊?会不会是用gcc编译时加了什么特殊选项的原故?
回复

使用道具 举报

 楼主| 发表于 2004-8-16 16:27:38 | 显示全部楼层
第一段的确会有无限循环的情况出现

但是第二段我式了,没有问题

ps:这两段程序是从《程序员》上看的

上面说会产生死循环
回复

使用道具 举报

发表于 2004-8-16 16:50:27 | 显示全部楼层
第一段程序我估计应该是这样一个流程:先执行addr()函数,在函数中将局部变量的地址赋给指针p,实际上现在p指向的是程序堆栈的一个地址;再执行loop()函数,在函数中定义了两个局部变量i和j,这时由于定义次序的问题,i变量和addr()函数中“曾经”定义过的变量k的地址是重合的,也就是说现在指针p指向的是局部变量i,所以──当(*p)--时,实际上就是i--,所以就会出现i和*p恒为定值的情况。
回复

使用道具 举报

 楼主| 发表于 2004-8-16 16:56:14 | 显示全部楼层
嗯,

差不多,应该是这样

但是第二个程序根本就不是死循环。
回复

使用道具 举报

发表于 2004-8-16 17:11:36 | 显示全部楼层
第二段就是一个普通的数组赋值的循环,只不过它赋过了头而已,也才过头一个int单位,估计是那哥们儿的编译器有问题吧……
回复

使用道具 举报

 楼主| 发表于 2004-8-16 17:14:56 | 显示全部楼层
  
回复

使用道具 举报

发表于 2004-8-16 20:01:25 | 显示全部楼层
第一段确实是死循环,p指向栈中的第一个元素(因为声明局部变量k),而addr()函数运行结束后将局部变量销毁,而loop()函数声明的i也是占用了栈中的第一个位置(以long类型的单位),所以这时p正好指向i,所以循环中(*p)=0让i总是回到起点值而形成死循环。

第二段没发现什么问题呀,平时也是这么用的呢。
回复

使用道具 举报

发表于 2004-8-24 15:18:06 | 显示全部楼层
void addr(){
              long k;
              k=0;
              p=&k;
}
出了问题,改
void addr(){
              long *k=(long *)malloc(sizeof(long));
              *k=0;
              p=k;
}
(可以省里面的k,用全局p)
回复

使用道具 举报

发表于 2004-8-27 17:01:34 | 显示全部楼层
唉,不能不说了,第二段程序给a[10]赋值了,如如果不是编译器特别处理的话 i又将变成0,你没有变成无线循环可能是你原则了优化,你试试o0看看
回复

使用道具 举报

发表于 2004-8-27 21:32:46 | 显示全部楼层
哦,i<=10,问题出在=上,说明多数人是粗心的。
回复

使用道具 举报

发表于 2004-8-28 10:17:24 | 显示全部楼层
在addr()函数中
long k;
它在函数返回时为k分配的内存已经收回了,*p的值并不是k的值
第二个问题可以用个内存填充就搞定了
memset(n, 0, sizeof(int)*10);
回复

使用道具 举报

发表于 2004-9-3 21:57:58 | 显示全部楼层
第2个例子在dos和linux下的现象是不同的   
回复

使用道具 举报

发表于 2004-9-4 19:56:54 | 显示全部楼层
[quote:72d29da85e="weiasd"]唉,不能不说了,第二段程序给a[10]赋值了,如如果不是编译器特别处理的话 i又将变成0,你没有变成无线循环可能是你原则了优化,你试试o0看看[/quote]这个怎么说?是不是说 i 在栈的最底,a[]里面a[9]是在最底,所以它的下面就是 i 了?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-7 13:29 , Processed in 0.062992 second(s), 16 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表