Fortran Coder

标题: 递归子程序释放实参指针的内存 [打印本页]

作者: jovan    时间: 2015-12-9 11:21
标题: 递归子程序释放实参指针的内存
定义了个八叉树的数据结构
[Fortran] 纯文本查看 复制代码
type facept
      integer(4) :: dep               !深度
      integer(4) :: fac               !当前占据点
      real(8), dimension(3) :: cx
      logical :: leaf,ocp             !leaf:是否为叶子(无分支);ocp:是否被占据
      type(facept), pointer :: NT0,NT1,NT2,NT3,NT4,NT5,NT6,NT7,NT8
   end type facept

[Fortran] 纯文本查看 复制代码
type(facept), pointer :: pp
allocate(pp)

使用过程中指针的八叉树结构分了很多级,现在使用完了想释放掉所有赋给指针的内存
[Fortran] 纯文本查看 复制代码
recursive subroutine release
   use octree
   implicit none
   
   if(.not. pp%leaf) then
      pp=>pp%NT1
      call release
      deallocate(pp%NT1)
      pp=>pp%NT2
      call release
      deallocate(pp%NT2)
      pp=>pp%NT3
      call release
      deallocate(pp%NT3)
      pp=>pp%NT4
      call release
      deallocate(pp%NT4)
      pp=>pp%NT5
      call release
      deallocate(pp%NT5)
      pp=>pp%NT6
      call release
      deallocate(pp%NT6)
      pp=>pp%NT7
      call release
      deallocate(pp%NT7)
      pp=>pp%NT8
      call release
      deallocate(pp%NT8)
   end if
      
   pp=>pp%NT0
   
end subroutine

这样从进程管理器中可以看出明显内存减小了很多,也就是释放掉了内存,但是感觉效率有点低,尤其是数据量大的时候释放的很慢,感觉到可能哪里不太合理,于是又写个个:
[Fortran] 纯文本查看 复制代码
recursive subroutine release(tp)
   use octree
   implicit none
   type(facept), pointer :: tp
   
   if(.not. tp%leaf) then
      call release(tp%NT1)
      call release(tp%NT2)
      call release(tp%NT3)
      call release(tp%NT4)
      call release(tp%NT5)
      call release(tp%NT6)
      call release(tp%NT7)
      call release(tp%NT8)
   else
      deallocate(tp)
   end if
   
end subroutine

这样改完之后编译运行都没有问题,但是并没有释放掉内存,大家帮忙看下怎么回事,如何高效的释放掉内存,谢谢!!

作者: 好小爱新    时间: 2015-12-9 17:15
allocate不建议大量使用,可以先确定规模然后线性存储,一次分配多次使用。
作者: jovan    时间: 2015-12-9 17:40
本帖最后由 jovan 于 2015-12-9 17:43 编辑
好小爱新 发表于 2015-12-9 17:15
allocate不建议大量使用,可以先确定规模然后线性存储,一次分配多次使用。 ...

但是有时候不知道要用到多大的数组,计算的过程中才知道要用多大,尤其是这种空间八叉树结构,也不知道要分多少层子结构,只有满足一定条件了才停止往下八分,只能是八分一次,给新生成的八叉树赋内存,现在就是想反过来从最底层到最上层遍历一遍释放内存,第一种方法可行,感觉效率有点低,第二种方法不可行,麻烦给看下递归的过程中有没有什么问题,第二种的形参会返回空内存,可能会出现问题,而且我在call release(cp%NT1)之后print *, associated(cp%NT1), 竟然还有些为TRUE的,按道理应该全部是FALSE才对的,麻烦给看下吧,谢谢
作者: 好小爱新    时间: 2015-12-9 17:50
jovan 发表于 2015-12-9 17:40
但是有时候不知道要用到多大的数组,计算的过程中才知道要用多大,尤其是这种空间八叉树结构,也不知道要 ...

当tp%leaf为真时,您并没有释放NT1到8,而之前的程序是释放了的。所以自然会有一部分内存没有释放。
作者: jovan    时间: 2015-12-10 11:44
好小爱新 发表于 2015-12-9 17:50
当tp%leaf为真时,您并没有释放NT1到8,而之前的程序是释放了的。所以自然会有一部分内存没有释放。 ...

当tp%leaf为真时,就代表没有子指针,也就没有NT1到8,我还是怀疑形参实参传递有问题,这样改就可以了:
[Fortran] 纯文本查看 复制代码
recursive subroutine release(tp)
   use octree
   implicit none
   type(facept), pointer :: tp !,ap
   
   if(.not. tp%leaf) then
      call release(tp%NT1)
      deallocate(tp%NT1)
      call release(tp%NT2)
      deallocate(tp%NT2)
      call release(tp%NT3)
      deallocate(tp%NT3)
      call release(tp%NT4)
      deallocate(tp%NT4)
      call release(tp%NT5)
      deallocate(tp%NT5)
      call release(tp%NT6)
      deallocate(tp%NT6)
      call release(tp%NT7)
      deallocate(tp%NT7)
      call release(tp%NT8)
      deallocate(tp%NT8)
   end if
   
   end subroutine

这样就不用传递空指针了,谢谢您的回复
作者: pasuka    时间: 2015-12-10 13:59
为啥不用现成的C或C++库呢?
用Fortran的话,得自己造轮子还未必好用




欢迎光临 Fortran Coder (http://bbs.fcode.cn/) Powered by Discuz! X3.2