У меня проблема с попыткой определить подпрограмму, аргумент которой содержит назначаемую, необязательную переменную намерения (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
Основной test_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
Кстати, я тоже пробовал использовать массив фиксированного размера, но все равно не помогает. Интересно, нельзя ли такое делать?