2

我在尝试定义一个子例程时遇到问题,该子例程的参数包含一个可分配的、可选的、意图(inout)变量,如下所示。代码编译正常,但出现“分段错误 - 无效内存引用”的运行时错误。

子程序 test_routine.f90

SUBROUTINE test_routine(A,B)

IMPLICIT NONE

    REAL,ALLOCATABLE,INTENT(IN)               :: A(:,:)
    REAL,ALLOCATABLE,OPTIONAL,INTENT(INOUT)   :: B(:,:)

    B = A
    B(:,:) = 1

END SUBROUTINE

该子例程封装在一个模块中,并在 Main 中调用。

模块 test_module.f90

MODULE test_module

IMPLICIT NONE

    INTERFACE test_routine
        MODULE PROCEDURE test_routine
    END INTERFACE

END MODULE test_module

主要测试_main.f90

PROGRAM main

    USE test_module

IMPLICIT NONE

    REAL,ALLOCATABLE    :: A(:,:),B(:,:)

    ALLOCATE(A(6,6))
    ALLOCATE(B(6,6))
    A(:,:) = 0
    CALL test_routine(A,B)    ! WORKS FINE
    CALL test_routine(A)      ! DOESN'T WORK!

END PROGRAM main

然后我尝试分配另一个变量op_B,以弥补B,如果主程序没有传入它,它实际上并不存在。但是下面的代码仍然不起作用。

SUBROUTINE test_routine(A,B)

IMPLICIT NONE

    REAL,ALLOCATABLE,INTENT(IN)    :: A(:,:)
    REAL,ALLOCATABLE,OPTIONAL,INTENT(INOUT)   :: B(:,:)
    REAL,ALLOCATABLE               :: op_B(:,:)

    IF(.NOT. PRESENT(B)) THEN
        ALLOCATE(op_B(SIZE(A,1),SIZE(A,2)))
        B = op_B
    END IF
    B = A
    B(:,:) = 1

END SUBROUTINE

顺便说一句,我也尝试过使用固定大小的数组,但仍然没有帮助。我想知道是否不可能做这样的事情?

4

2 回答 2

2

虚拟参数可以是可选的、可分配的和意图(inout)。

但是您不能定义或引用可选的虚拟参数,禁止将其传递给 PRESENT 或将其与另一个可选参数相关联。如果“B”不存在,则不能执行“B = A”。

于 2017-08-15T03:17:27.103 回答
0

根据@lanH 的回答,我目前想出的唯一方法是为每个可选的虚拟参数提供一个别名。这个版本现在可以工作了。

SUBROUTINE test_routine(A,B)

IMPLICIT NONE

    REAL,ALLOCATABLE,INTENT(IN)    :: A(:,:)
    REAL,ALLOCATABLE,OPTIONAL,INTENT(INOUT)   :: B(:,:)
    REAL,ALLOCATABLE               :: op_B(:,:)

    ALLOCATE(op_B(SIZE(A,1),SIZE(A,2)))
    op_B = A
    op_B(:,:) = 1

    IF(PRESENT(B)) THEN
        B = op_B
    END IF

    DEALLOCATE(op_B)

END SUBROUTINE
于 2017-08-15T18:01:57.813 回答