Fortran COMMON块中带指针的自定义类型传递异常求解
问题原因
- Fortran标准明确规定,包含指针成员的派生类型,即便声明了
sequence属性,也不能通过COMMON块跨程序单元传递指针的关联状态。COMMON块仅支持传递普通连续存储的静态数据,而指针本质是存储内存地址的特殊变量,其关联状态(是否指向合法内存、指向的内存范围、数组维度信息)属于当前程序单元的局部信息,不会通过COMMON块同步到其他子程序中。 - 你示例中的子程序访问
my_array%i时,实际访问的是未关联的野指针,属于未定义行为,因此输出了异常的全1结果。
修复方案
根据你的代码改造接受度,可以选择以下两种方案:
方案1:使用模块共享变量(推荐,符合现代Fortran规范)
将派生类型定义和需要共享的变量封装在独立模块中,主程序和子程序统一引用该模块,完全替代COMMON块,示例代码如下:
module dynarr_mod implicit none type :: intdynarr2 integer, pointer :: i(:,:) => null() end type intdynarr2 type(intdynarr2) :: my_array end module dynarr_mod program main use dynarr_mod implicit none integer :: j,k allocate(my_array%i(1:10,1:10)) do j = 1,10 do k = 1,10 my_array%i(j,k) = j * k end do end do write(*,*) my_array%i call printarr deallocate(my_array%i) end program main subroutine printarr use dynarr_mod implicit none write(*,*) my_array%i end subroutine
方案2:兼容旧代码的最小改动方案
如果现有代码改造量过大无法替换COMMON块,可以将带指针的派生类型作为子程序的显式入参传递,不需要通过COMMON块共享,示例代码如下:
implicit none type :: intdynarr2 sequence integer, pointer :: i(:,:) end type intdynarr2 type(intdynarr2) :: my_array integer :: j,k allocate(my_array%i(1:10,1:10)) do j = 1,10 do k = 1,10 my_array%i(j,k) = j * k end do end do write(*,*) my_array%i call printarr(my_array) deallocate(my_array%i) end subroutine printarr(arr) implicit none type :: intdynarr2 sequence integer, pointer :: i(:,:) end type intdynarr2 type(intdynarr2), intent(in) :: arr write(*,*) arr%i end subroutine
内容的提问来源于stack exchange,提问作者DerAuenlaender
相关产品推荐
相关产品推荐

