当前位置: 首页 > 程序语言 >【求助】Fortran里面Stack Overflow【已完成】

【求助】Fortran里面Stack Overflow【已完成】

作者 jhuiuc
来源: 小木虫 450 9 举报帖子
+关注

Visual Fortran, 程序里面定义了一个整型数组 JS(N), 所有A-H, O-Z参数和数组定义为Real*8类型. 这个数组在Call语句被用到, Call Sub1(A, B, JS).

当N取352以下时, 程序完全正常, 再大就会出现severe 170 -Stack Overflow 的错误信息(Debug时指向这个JS(N)数组).
severe(170): Program Exception - stack overflow
FOR$IOS_PGM_STKOVF. The Compaq Fortran RTL has detected a stack overflow while executing your program. See your Release Notes for information on how to increase stack size.

1. 如何查这个Release Notes?
2. 如何增加Stack Size?
3. 欢迎其他任何相关评论. 如果需要我补充其它信息, 请指出.

程序大概结构是(本身没有任何语言问题, 就是修改N值的时候会出现Overflow现象):
Program Main
Implicit real*8 (A-H, O-Z)
Parameter (N=300)
Integer JS(N)
Real*8 A1(N, N), B1(N,N),X1(N)
......
......
CALL Sub1(A1,B1,N,X1,LL,JS) (A1,B1是2维数组, X1是1维数组, LL是整型数)
......
......
END

SUBROUTINE Sub1(A1,B1,N,X1,LL,JS)
......
......
Return
End

[ Last edited by wangen994 on 2010-1-18 at 12:05 ]

 返回小木虫查看更多

今日热帖
  • 精华评论
  • magic7004

    一般默认的stack size是足够的,通常stack overflow 都是某些bug或者很恶劣的算法导致的。
    建议搂住修改一下代码,减小stack的使用。比如避免递归调用,避免把很大的结构放在stack里等。建议搂住把大的结构或者数组放在heap里,把递归改成循环。

    ps:stack的大小通常是通过调整编译器的参数修改的,这个去找编译器的文档吧。

  • magic7004

    貌似楼主有两个N X N维的数组,如果这个是放在stack里的话,那就是非常大的了。
    我不清楚FORTRAN的语法,不知道楼主声明数组的方式是不是会把数组放在stack里。
    如果是放在stack里的话,建议搂住把数组放到Heap里。

    ps:stack就是堆栈,Heap就是堆。每个线程都有自己的stack用来保存局部变量和函数调用信息,根据编译器不同,通常大小1~4MB之间,如果用完了就会出现stack overflow exception。
    如果楼主不清楚的话,建议看一下Fortran语法关于内存管理的部分,非常大的数组应该是动态管理的,放在heap里。。

    [ Last edited by magic7004 on 2010-1-16 at 16:50 ]

  • maomao1210

    引用回帖:
    Originally posted by jhuiuc at 2010-1-16 16:25:
    Visual Fortran, 程序里面定义了一个整型数组 JS(N), 所有A-H, O-Z参数和数组定义为Real*8类型. 这个数组在Call语句被用到, Call Sub1(A, B, JS).

    当N取352以下时, 程序完全正常, 再大就会出现severe 170 -Sta ...

    这样修改:stack size
    是我从我们群里截的图。答案是某个大侠给出来的。可以参考一下。

    [ Last edited by maomao1210 on 2010-1-16 at 19:41 ]

  • hakekill

    这个问题好像有人问过了,我还是推荐使用动态分配数组来做,省心省事

  • maomao1210

    引用回帖:
    Originally posted by jhuiuc at 2010-1-16 16:25:
    Visual Fortran, 程序里面定义了一个整型数组 JS(N), 所有A-H, O-Z参数和数组定义为Real*8类型. 这个数组在Call语句被用到, Call Sub1(A, B, JS).

    当N取352以下时, 程序完全正常, 再大就会出现severe 170 -Sta ...

    你好,栈空间是用来存放局部变量,参数地址的内存区域,如果你内存足够大,一般不会有什么问题。
    像你程序中出现的问题,如果不重新革新代码的话,就两种方法可以选择,第一就是增大栈空间大小,其次就是该为使用堆(heap),也就是 hakekill 虫子说的,动态分配数组大小。 既然你设为100M可以运行的话,一般不会有问题的。我不知道你机器内存多大。

    [ Last edited by maomao1210 on 2010-1-17 at 14:56 ]

  • maomao1210

    引用回帖:
    Originally posted by magic7004 at 2010-1-16 16:38:
    一般默认的stack size是足够的,通常stack overflow 都是某些bug或者很恶劣的算法导致的。
    建议搂住修改一下代码,减小stack的使用。比如避免递归调用,避免把很大的结构放在stack里等。建议搂住把大的结构或者数 ...

    强烈建议楼主采纳magic7004 的建议,把代码重新革新一下,呵呵。

  • magic7004

    引用回帖:
    jhuiuc(金币+10,VIP+0):虽然我写过很多Fortran,但还不知道什么是Heap,能给个例句吗?C语言的也可以 1-16 19:09

    C++的例子吧
    int a[100];
    这个数组a就是放在stack里的,会占用400字节的栈空间。
    int* b = new int[100];
    这个数组b就是放在堆里的,它会占用4个字节的栈空间和400字节的堆空间。
    所以如果 int a[300][300];
    就会占用300*300*4 = 360k的栈空间,如果的栈默认大小是1M,那么程序理有几个这样的数组就很容易造成stack overflow.
    所以上面程序要改成
    typedef int p[300];
    p* a = new p[300];
    这样的话就只会占用4个字节的栈空间,其余的数据在堆里。而堆空间是没有大小限制的,理论上可以分配到2G的用户内存空间(32位Windows的默认配置)被用完为止。

    [ Last edited by magic7004 on 2010-1-18 at 11:50 ]

猜你喜欢
下载小木虫APP
与700万科研达人随时交流
  • 二维码
  • IOS
  • 安卓