【问题标题】:Deallocating memory with destructor in Fortran在 Fortran 中使用析构函数释放内存
【发布时间】:2014-11-12 11:32:39
【问题描述】:

基础:我正在尝试使用构造函数和析构函数在 Fortran 中编写好的代码。 这是一个非常简单的Test 类的示例,它是客户端:

module test_class_module
implicit none

type :: Test
private
integer, allocatable :: arr(:)
 CONTAINS
    final :: destructor
end type

interface Test
    procedure :: constructor
end interface

 CONTAINS
    function constructor(arr_size) result(this)
        type(Test) :: this
        integer, intent(in) :: arr_size
        write(*,*) 'Constructor works'
        allocate(this % arr(arr_size))
    end function

    subroutine destructor(this)
        type(Test) :: this
        write(*,*) 'Destructor works'
        if (ALLOCATED(this % arr)) deallocate(this % arr)
    end subroutine        
end module

program test_client
    use test_class_module

    type(Test) :: tst
    tst = Test(100)
end

问题: 我用valgrind 运行它并打印出来:

Constructor works
Destructor works
Destructor works
==22229== HEAP SUMMARY:
==22229== in use at exit: 432 bytes in 2 blocks
==22229== total heap usage: 10 allocs, 8 frees, 13,495 bytes allocated

问题:为什么还要分配内存? (P.S. 我理解需要赋值运算符才能正确使用类,但这对于这个问题是不够的)感谢您的任何想法。

【问题讨论】:

    标签: memory-management constructor fortran valgrind destructor


    【解决方案1】:

    实际上,不应在程序结束时为tst 调用析构函数。根据最新标准,主程序变量隐式为saved。因此,它应该只为 rhs 上的函数结果调用 destructor,在赋值中被覆盖时调用 tst

    【讨论】:

    • save 属性是否仅在 end 阻止最终确定,而不是在 tst 最终确定为内部分配的 lhs 的情况下?那么,应该产生两个最终确定?
    • 是的,关键是它最后没有完成,数组仍然被分配。类似:software.intel.com/en-us/forums/topic/271088
    • 啊,是的,我现在明白你的意思了。 tst 完成一次,但关键不是在最后。 [我对“不应该为 tst 调用析构函数”感到困惑。]
    • 所以,答案是:“析构函数工作得很好,但不适用于主程序。在这种情况下内存泄漏是可以的。”是吗?
    • 没错,对于主程序中定义的变量和模块变量,您必须自己调用终结器。
    【解决方案2】:

    为了后代。 如果将测试程序中的三行包装在BLOCK 中,您将看到所需的行为。我只修改了你的主程序:

    program test_client
        use test_class_module
        write(*,*) '1 program start'
        BLOCK
            type(Test) :: tst
            write(*,*) '2 calling constructor'
            tst = Test(100)
            write(*,*) '3 block ending'
        END BLOCK
        write(*,*) '4 program end'
    end
    

    这会产生:

    valgrind bin/SimpleTest
    ==10031== Memcheck, a memory error detector
    ...
    1 program start
    2 calling constructor
    Constructor works
    3 block ending
    Destructor works
    4 program end
    ==10031== 
    ==10031== HEAP SUMMARY:
    ==10031==     in use at exit: 0 bytes in 0 blocks
    ==10031==   total heap usage: 22 allocs, 22 frees, 12,417 bytes allocated
    ==10031== 
    ==10031== All heap blocks were freed -- no leaks are possible
    ==10031== 
    ==10031== For counts of detected and suppressed errors, rerun with: -v
    ==10031== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
    

    【讨论】:

      猜你喜欢
      • 2016-10-25
      • 1970-01-01
      • 2017-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-04
      • 2017-05-25
      • 2020-05-25
      相关资源
      最近更新 更多