You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 15:39:01