gha*_*ooo 4 stack-overflow fortran
我的简单Fortran程序有问题.我在Fortran 77工作,使用Compaq Visual Fortran.程序结构必须采用主程序和子程序的形式,因为它是与有限元方法相关的大程序的一部分.
我的问题是,我想设置的值10000和10000 NHELE和NVELE分别,但是当我运行的代码,程序停止,并提供了以下错误:
forrt1: server <170>: program Exception - stack overflow
Run Code Online (Sandbox Code Playgroud)
我已经尝试迭代地减少所需的值,直到我达到507和507.此时代码运行没有错误.
但是,将值增加到508和508会导致重新出现相同的错误.
我认为这个问题与子程序有关NIGTEE,因为当我没有它重新安排程序时,一切正常.
我已经尝试使用菜单将堆栈大小增加到最大值,project>>settings>>link>>output>>reserve & commit
但这并没有什么区别.
我怎么解决这个问题?
这是我的计划:
PARAMETER(NHELE=508,NVELE=508)
PARAMETER(NHNODE=NHELE+1,NVNODE=NVELE+1)
PARAMETER(NTOTALELE=NHELE*NVELE)
DIMENSION MELE(NTOTALELE,4)
CALL NIGTEE(NHELE,NVELE,NHNODE,NVNODE,NTOTALELE,MELE)
OPEN(UNIT=7,FILE='MeshNO For Rectangular.TXT',STATUS='UNKNOWN')
WRITE(7,500) ((MELE(I,J),J=1,4),I=1,NTOTALELE)
500 FORMAT(4I20)
STOP
END
SUBROUTINE NIGTEE(NHELE,NVELE,NHNODE,NVNODE,NTOTALELE,MELE)
DIMENSION NM(NVNODE,NHNODE),NODE(4)
DIMENSION MELE(NTOTALELE,4)
KK=0
DO 20 I=1,NVNODE
DO 20 J=1,NHNODE
KK=KK+1
NM(I,J)=KK
20 CONTINUE
KK=0
DO 30 I=1,NVELE
DO 30 J=1,NHELE
NODE(1)=NM(I,J)
NODE(2)=NM(I,J+1)
NODE(3)=NM(I+1,J+1)
NODE(4)=NM(I+1,J)
KK=KK+1
DO 50 II=1,4
50 MELE(KK,II)=NODE(II)
30 CONTINUE
RETURN
END
Run Code Online (Sandbox Code Playgroud)
谢谢.
更新:
这是你的实际问题.您的NM数组被NHNODE按NVNODE行声明为二维单元格数组.如果这是10,000乘10,000,那么除了程序使用的任何其他内存之外,你需要超过381兆字节的内存才能单独分配这个数组.(相比之下,如果阵列是500乘500,那么同一阵列只需要大约1兆字节的内存.)
问题是旧的Fortran会直接在代码段或堆栈中分配所有数组.操作系统"堆"(大型对象的通用内存)的概念是在1977年发明的,但Fortran 77仍然没有任何构造可以使用它.因此,每次调用子例程时,都必须推送堆栈指针,以便为堆栈上的381 MB空间腾出空间.这几乎可以肯定大于操作系统允许堆栈段的空间量,并且堆栈内存溢出(从而导致堆栈溢出).
解决方案是从不同的地方分配内存.我知道在旧的Fortran中,可以使用COMMON块直接从代码段静态分配内存.您仍然无法动态分配更多,因此您的子例程不能重入,但如果您的子例程一次只调用一次(看起来是这样),这可能是最佳解决方案.
更好的解决方案是切换到Fortran 90或更新版本并使用ALLOCATE关键字在堆上而不是堆栈上动态分配数组.然后你可以像操作系统给你的那样分配一个大块,但你不必担心堆栈溢出,因为内存将来自另一个地方.
您可以通过在编译器中更改它来修复此问题,如MSB建议的那样,但更好的解决方案是简单地修复代码.