| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1239 人关注过本帖
标题:请大家看一下这小段代码,为什么运行一会就会停止
只看楼主 加入收藏
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
你检查过j的值吗?

授人以渔,不授人以鱼。
2015-08-18 22:13
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
如无意外,你崩溃的时候,j应在32000左右。

授人以渔,不授人以鱼。
2015-08-18 23:16
wmf2014
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:216
帖 子:2039
专家分:11273
注 册:2014-12-6
收藏
得分:0 
回复 12楼 TonyDeng
传说默认栈空间不是1M么,1M=2^20,一个int占用4字节=2^2,那么数组最大空间应有2^18=262144,扣除系统用的部分空间,j的值保守估计也得有200000以上啊。实际上到底是多少呢?vc无法使用动态数组,我使用递归代码测试。
下述代码只定义了一个静态变量,不占栈空间,理论上递归时只有4个字节函数地址入栈,在我的电脑里测试,j的值大于12333时不显示结果(应该算崩溃吧),即j的最大值为12332,计算栈空间应为12332*4=49328,小于64K,难道vc默认的栈空间大小为64K?不知道我理解的有错误没。
程序代码:
#include <stdio.h>
int j=0;
int ff()
{
    if(j>12332)return 0;
    j++;
    ff();
    return 0;
}
void main()
{
    ff();
    printf("%d\n",j);
}


能编个毛线衣吗?
2015-08-19 06:25
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
不同编译器有不同的默认栈尺寸,微软的通常是1M。递归占用更多的栈,每次迭代要保存上一层函数的环境。楼主的编译器支持VLA,应该不是vc,gcc好像是默认4M吧。

[ 本帖最后由 TonyDeng 于 2015-8-19 09:53 编辑 ]

授人以渔,不授人以鱼。
2015-08-19 09:46
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
百度上有介绍递归的特点:

递归算法一般用于解决三类问题:

(1)数据的定义是按递归定义的。(Fibonacci函数)

(2)问题解法按递归算法实现。

这类问题虽则本身没有明显的递归结构,但用递归求解比迭代求解更简单,如Hanoi问题。

(3)数据的结构形式是按递归定义的。

如二叉树、广义表等,由于结构本身固有的递归特性,则它们的操作可递归地描述。

递归的缺点:

递归算法解题相对常用的算法如普通循环等,运行效率较低。因此,应该尽量避免使用递归,除非没有更好的算法或者某种特定情况,递归更为适合的时候。在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等。

授人以渔,不授人以鱼。
2015-08-19 09:51
q215236213
Rank: 4
等 级:业余侠客
威 望:1
帖 子:148
专家分:276
注 册:2012-7-24
收藏
得分:0 
数组定义的时候,那个大小能使用变量 ?  int  a[j] 这样定义 编译器不报错? 定义数组必须是一个确定的大小值,在编译的时候就要确定下来!
2015-08-19 11:19
wmf2014
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:216
帖 子:2039
专家分:11273
注 册:2014-12-6
收藏
得分:0 
回复 14楼 TonyDeng
的确是1M。
进入调试状态,查看汇编代码,发现每递归一次使用栈空间84字节,所以栈空间=84*12332=1035888≈1M。
早期写汇编时,多只需要保存自己需要的寄存器即可,但c编译器似乎对每个函数调用都空出64字节的空间就填充0xcccccccc。
程序代码:
00401020   push        ebp
00401021   mov         ebp,esp
00401023   sub         esp,40h  //此处留出64字节,64+4个push*4+1个call*4=84字节(这是不做任何变量定义的情况)
00401026   push        ebx
00401027   push        esi
00401028   push        edi
00401029   lea         edi,[ebp-40h]
0040102C   mov         ecx,10h
00401031   mov         eax,0CCCCCCCCh  //填充64个0xcc
00401036   rep stos    dword ptr [edi]

能编个毛线衣吗?
2015-08-19 12:19
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
栈尺寸是可以在链接参数中调整的,但那种不合理的用法,怎么改都是治标不治本,隐患还是摆在那。自己知道潜在问题还好,不知道的,就是程序设计缺陷了。尤其是用递归的,恰好往往是迭代次数未知的场合,不死是侥幸——人家书上都有教凡写递归,都应设置一个静态变量作计数器统计次数,以免溢出崩溃,可这里学和写递归的,没见过有这种意识,还总是吹捧递归有多高明。

授人以渔,不授人以鱼。
2015-08-19 12:26
qq383264679
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:155
专家分:130
注 册:2012-1-19
收藏
得分:0 
回复 18楼 TonyDeng
为何这么较真·········
2015-08-19 16:20
wan_sz
Rank: 1
等 级:新手上路
帖 子:2
专家分:0
注 册:2014-2-20
收藏
得分:0 
内存爆了
2015-08-19 17:15
快速回复:请大家看一下这小段代码,为什么运行一会就会停止
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.017997 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved