如何判断fortran数组指针是直接分配还是与另一个对象相关联?

fab*_*tti 5 arrays fortran pointers memory-leaks fortran90

我正在使用包含一些数组指针的fortran代码; 根据用户输入,它们可能被设置为指向具有赋值语句的另一个数组=>,或者它们可能直接与allocate语句一起分配.

这会在代码末尾释放内存时产生问题,因为在第一种情况下我只想要nullify指针,而在第二种情况下我需要deallocate它以防止内存泄漏.问题是在两种情况下都associated返回true,所以我不知道如何在没有手动跟踪的情况下判断我所处的情况.由于有许多这样的数组指针,我宁愿避免这样做.

有没有一种简单的方法来区分这两种情况?

谢谢!

chw*_*w21 6

这听起来像一个可怕的混乱.我假设你有这样的事情:

program really_bad
    implicit none
    integer, dimension(:), pointer :: a
    integer, dimension(:), allocatable, target :: b
    logical :: point_to_b

    allocate(b(10))
    write(*, *) "Should I point to B?"
    read(*, *) point_to_b

    if (point_to_b) then
        a => b
    else
        allocate(a(10))
    end if

    ! Destroy A

end program really_bad
Run Code Online (Sandbox Code Playgroud)

你的问题是毁灭性的部分.如果a指向b,那么你想要NULLIFY它,因为你需要保持b.但是,如果a没有指向b,只有NULLIFY它,你会得到内存泄漏.

正如@ ian-bush指出的那样,你可以检查某些东西是否与其他东西相关联,但这意味着你必须将指针与所有可能的目标进行比较,并且你声称你有很多这些目标.

你可以尝试一件事,但这可能更糟糕的一个想法,就是尝试解除分配,并使用其STAT=伪参数来检查释放是否真的有效.请注意,这是一个可怕的黑客攻击,我只能在英特尔上工作,而不是在GFortran上工作,但这里什么也没做:

program don
    implicit none
    integer, dimension(:), pointer :: a
    integer, dimension(:), target, allocatable :: b
    logical :: point_to_b
    integer :: stat

    allocate(b(10))
    b = (/ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 /)
    write(*, *) "Should I point to B?"
    read(*, *) point_to_b
    if ( point_to_b ) then
        a => b
    else
        allocate(a(10))
    end if
    deallocate(a, stat=stat)
    if ( stat /= 0 ) nullify(a)
end program don
Run Code Online (Sandbox Code Playgroud)

一个更好的方法可能是用具有指针和标志的类型替换你的数组指针.

program don
    implicit none
    type :: my_array_pointer_type
        integer, dimension(:), pointer :: array
        logical :: master
    end type my_array_pointer_type
    type(my_array_pointer_type) :: a
    integer, dimension(:), target, allocatable :: b
    logical :: point_to_b
    integer :: stat

    allocate(b(10))

    b = (/ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 /)
    write(*, *) "Should I point to B?"
    read(*, *) point_to_b
    if ( point_to_b ) then
        a%master = .false.
        a%array => b
    else
        a%master = .true.
        allocate(a%array(10))
    end if

    if (a%master) then
        deallocate(a%array)
    else
        nullify(a%array)
    end if
end program don
Run Code Online (Sandbox Code Playgroud)

如果您可能将另一个指针指向,a然后尝试销毁它,这些建议都不会对您有所帮助.在这种情况下,我真的建议重新考虑整个项目设计.