21

以下代码返回分段错误,因为我试图传递的可分配数组没有被正确识别(大小返回 1,而它应该是 3)。在此页面 (http://www.eng-tips.com/viewthread.cfm?qid=170599) 中,一个类似的示例似乎表明它在 F95 中应该可以正常工作;我的代码文件具有 .F90 扩展名,但我尝试将其更改为 F95,并且我正在使用 gfortran 进行编译。

我的猜测是问题应该出在我将可分配数组传递给子程序的方式上;我究竟做错了什么?

!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%!
 PROGRAM test
!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%!
 IMPLICIT NONE
 DOUBLE PRECISION,ALLOCATABLE :: Array(:,:)
 INTEGER                      :: iii,jjj

 ALLOCATE(Array(3,3))
 DO iii=1,3
 DO jjj=1,3
    Array(iii,jjj)=iii+jjj
    PRINT*,Array(iii,jjj)
 ENDDO
 ENDDO
 CALL Subtest(Array)

 END PROGRAM
!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%!
 SUBROUTINE Subtest(Array)
 DOUBLE PRECISION,ALLOCATABLE,INTENT(IN) :: Array(:,:)
 INTEGER                                 :: iii,jjj

 PRINT*,SIZE(Array,1),SIZE(Array,2)
 DO iii=1,SIZE(Array,1)
 DO jjj=1,SIZE(Array,2)
    PRINT*,Array(iii,jjj)
 ENDDO
 ENDDO

 END SUBROUTINE
!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%!
4

3 回答 3

32

如果过程具有可分配的虚拟参数,则在任何调用范围内都需要显式接口。

(有很多东西需要显式接口,可分配的虚拟对象就是其中之一。)

您可以通过在主程序中为您的子例程放置一个接口块来自己提供该显式接口。另一种更好的选择是将子例程放在模块中,然后在主程序中使用该模块-然后自动创建显式接口。在您提供链接的 eng-tips 网站上有一个示例 - 请参阅 xwb 的帖子。

请注意,只有当您要执行与其分配状态相关的操作时,虚拟参数才有意义具有可分配属性 - 查询其状态、重新分配、解除分配等。

于 2012-10-24T23:23:50.337 回答
8

另请注意,您的可分配虚拟参数array是用 声明的intent(in),这意味着它的分配状态将是相关实际参数的分配状态(并且在过程中可能不会更改)。传递给子例程的实际参数可能未分配,因此即使使用显式接口也无法引用。编译器不会知道这一点,并且size在这种情况下,查询的行为是未定义的。

因此,在引用其内容之前,您首先必须检查arraywith的分配状态。我会进一步建议使用andallocated(array)在整个数组上实现循环,因为通常你不能确定's bounds:lbounduboundarray

subroutine subtest(array)
  double precision, allocatable, intent(in) :: array(:,:)
  integer                                   :: iii, jjj

  if(allocated(array)) then
    print*, size(array, 1), size(array, 2)
    do iii = lbound(array, 1), ubound(array, 1)
      do jjj = lbound(array, 2), ubound(array, 2)
        print*, array(iii,jjj)
      enddo
    enddo
  endif  
end subroutine
于 2012-10-25T16:09:41.370 回答
2

这是一个简单的示例,它在模块中使用可分配的虚拟参数。

module arrayMod   
  real,dimension(:,:),allocatable :: theArray    
end module arrayMod

program test
   use arrayMod
   implicit none

   interface
      subroutine arraySub
      end subroutine arraySub
   end interface

   write(*,*) allocated(theArray)
   call arraySub
   write(*,*) allocated(theArray) 
end program test

subroutine arraySub
   use arrayMod

   write(*,*) 'Inside arraySub()'
   allocate(theArray(3,2))
end subroutine arraySub
于 2016-07-11T20:40:38.037 回答