【问题标题】:Stack overflow with FortranFortran 堆栈溢出
【发布时间】:2012-04-15 11:28:30
【问题描述】:

我用 Compaq Visual Fortran 编写了一个程序。该程序没问题,并且在许多情况下都可以正常运行。我现在正在处理的案例更大,输入数据文件更大,当我运行程序时出现以下错误:

forrtl:severe(170): 程序异常 - 堆栈溢出

我安装了editbin.exe 程序,但我真的不知道如何使用它。输入时

editbin /STACK:4000000 DFDEV.exe

它告诉我它无法打开DFDEV.exe,即使我在包含该程序的目录中 (C:\Program Files\Microsoft Visual Studio\Common\MSDEV98\BIN)。 我真的不知道如何解决这个问题,在我在互联网上找到的关于这个主题的每个主题中,都没有关于如何使用这个 editbin 程序的说明。

【问题讨论】:

  • 如果您的问题是您的数据太大而无法放入堆栈,您可以考虑改为在堆上分配。
  • +1 @DavidHeffernan 的评论;特别是对于不使用动态分配的较旧的 fortran 程序,堆栈溢出几乎总是意味着子例程或函数中的大型静态数组变得太大而无法放入堆栈。根据您的操作系统,有一些变通方法,或者您可以说服您的编译器在堆上分配大型数组,但最重要的是开始努力完全不拥有如此大的静态数组,而是根据需要分配它们。跨度>
  • 如果数据非常大,您可以尝试使用 -share 之类的标志将其分配到堆中。我不知道正确的标志是否至少在 intel 编译器中是 -share 这个标志是 -share-intel
  • 在 Fortran 中,我相信这被称为“动态分配”。但是我对Fortran一无所知,所以我不知道语法。
  • Fortran 语言标准没有栈和堆的概念。一些编译器有一个编译时选项来控制数组是否放在堆栈上。可分配数组很可能放在堆上而不是栈上。

标签: fortran stack-overflow


【解决方案1】:

我还发现编译器“帮助”没有帮助。程序员指南提供了一些关于堆栈和堆分配的文字,可以通过搜索“commit”找到,并提示 EDITBIN.EXE 可用于修改已编译的 .exe 文件。正如后面提到的,还有编译器选项 Project>Settings>Link>Output 导致指定更大值的可能性,但对什么值几乎没有指导。

有一个编译器选项假设在子例程中声明的存储为 AUTOMATIC,但是,有些程序很可能依赖于在调用之间“静态”存储的数据,并且没有认真指定 SAVE。我一直小心保存,并没有注意到选择“自动”有任何影响。在我的例子中,在我引入了一点递归之后麻烦就开始了(在 Burroughs fortran 中自动可用 - RECURSIVE 关键字是多余的),但堆栈存储也用于临时变量(可能是数组大小)和复制输入、复制输出参数等作为数组部分,或者,例如,传递一个 blob 类型的数组,其中 blob 是一个复合实体,其中包含一个整数,并且您希望将整数表示为 A(i:j).Fred 中的数组,其中存储, Fred 的连续元素实际上并不相邻(stride = 1),因为 blob 还包含其他项。

无论如何,我开始使用分配的数组(以便有参差不齐的数组而不是 a(bigenough,n) 等)和其他更改,我刚刚检查并发现设置已恢复为默认值(空白条目),无疑是由于在电源出现故障后在新计算机上进行了重新安装。

【讨论】:

    猜你喜欢
    • 2011-08-13
    • 2010-12-11
    • 2019-05-18
    • 2012-12-20
    • 2011-03-02
    • 2011-08-22
    • 2023-03-04
    • 2014-01-17
    相关资源
    最近更新 更多