【问题标题】:array of pointers fortran指针数组 fortran
【发布时间】:2025-12-25 12:05:12
【问题描述】:

同样,Fortran 中的指针数组。好吧,我有一个派生类型:

type :: t_context_pointer  
    type(t_context),pointer :: p_ctx  
end type t_context_pointer

当我在主程序中做:

type(t_context_pointer),allocatable :: tab_ctx_ptr(:)  
type(t_context),allocatable,target :: ctx  
allocate(tab_ctx_ptr(1))  
allocate(ctx)  
tab_ctx_ptr(1)%p_ctx=>ctx

它有效。但是当我使用函数调用时:

type(t_context_pointer),allocatable,target :: tab_ctx_ptr(:)
allocate(tab_ctx_ptr(n))
call alloc_ctx(tab_ctx_ptr,n,1)

与其他地方:

subroutine alloc_ctx(tab_ctx_ptr,n,i)
    integer,intent(in) :: n,i
    type(t_context_pointer),intent(inout) :: tab_ctx_ptr(n)

    type(t_context),allocatable,target :: ctx

    allocate(ctx)
    tab_ctx_ptr(i)%p_ctx=>ctx
end subroutine

seg_fault 稍后在代码中。这里有什么问题吗?

【问题讨论】:

    标签: arrays pointers fortran


    【解决方案1】:

    ctx 在子例程 alloc_ctx 的范围内,并在您离开子例程后立即被释放。稍后访问它(通过指针)将导致段错误。

    在第一个示例中,您在主程序中分配了ctx,因此它的范围将一直到程序结束。

    你为什么不直接allocatetab_ctx_ptr(i)%p_ctx

    subroutine alloc_ctx(tab_ctx_ptr,n,i)
        integer,intent(in) :: n,i
        type(t_context_pointer),intent(inout) :: tab_ctx_ptr(n)
    
        allocate(tab_ctx_ptr(i)%p_ctx)
    end subroutine
    

    至于释放:您可以使用类似这样的方法来释放所有指针(但不是数组本身):

    subroutine dealloc_ctx(tab_ctx_ptr,n)
        integer,intent(in) :: n
        type(t_context_pointer),intent(inout) :: tab_ctx_ptr(n)
        integer            :: i
    
        do i=1,n
          ! Check whether the current element has an allocated element and 
          ! deallocate if necessary. 
          if ( associated(tab_ctx_ptr(i)%p_ctx) ) deallocate(tab_ctx_ptr(i)%p_ctx)
        enddo ! i
    end subroutine
    

    【讨论】:

    • 为什么要这样做,我的意思是不直接?事实上,这是计划管理多线程分配并确保数据在不同内存(例如 NUMA)中的局部性的更复杂代码的第一步。
    • 最后,如果有自动释放:如何在 C 代码中执行?
    • 我编辑了我的答案以展示一个示例...顺便说一句:检查分配的stat总是一个好主意!
    • 现在,我很困惑……什么 C 代码?你的例子是在 Fortran 中的?!
    • 我当然会检查,我只是简化了示例。顺便说一句:您的解决方案有效,所以首先,谢谢,其次,我确定我已经阅读了一个分配示例,例如我在论坛中的示例...