Fortran Coder

查看: 7079|回复: 5
打印 上一主题 下一主题

[指针] 递归子程序释放实参指针的内存

[复制链接]

7

帖子

2

主题

0

精华

入门

F 币
33 元
贡献
19 点
跳转到指定楼层
楼主
发表于 2015-12-9 11:21:33 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
定义了个八叉树的数据结构
[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

这样改完之后编译运行都没有问题,但是并没有释放掉内存,大家帮忙看下怎么回事,如何高效的释放掉内存,谢谢!!
分享到:  微信微信
收藏收藏1 点赞点赞 点踩点踩

6

帖子

0

主题

0

精华

入门

F 币
57 元
贡献
30 点
沙发
发表于 2015-12-9 17:15:35 | 只看该作者
allocate不建议大量使用,可以先确定规模然后线性存储,一次分配多次使用。

7

帖子

2

主题

0

精华

入门

F 币
33 元
贡献
19 点
板凳
 楼主| 发表于 2015-12-9 17:40:07 | 只看该作者
本帖最后由 jovan 于 2015-12-9 17:43 编辑
好小爱新 发表于 2015-12-9 17:15
allocate不建议大量使用,可以先确定规模然后线性存储,一次分配多次使用。 ...

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

6

帖子

0

主题

0

精华

入门

F 币
57 元
贡献
30 点
地板
发表于 2015-12-9 17:50:38 | 只看该作者
jovan 发表于 2015-12-9 17:40
但是有时候不知道要用到多大的数组,计算的过程中才知道要用多大,尤其是这种空间八叉树结构,也不知道要 ...

当tp%leaf为真时,您并没有释放NT1到8,而之前的程序是释放了的。所以自然会有一部分内存没有释放。

7

帖子

2

主题

0

精华

入门

F 币
33 元
贡献
19 点
5#
 楼主| 发表于 2015-12-10 11:44:33 | 只看该作者
好小爱新 发表于 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

这样就不用传递空指针了,谢谢您的回复

490

帖子

4

主题

0

精华

大宗师

F 币
3298 元
贡献
1948 点

水王勋章元老勋章热心勋章

6#
发表于 2015-12-10 13:59:13 | 只看该作者
为啥不用现成的C或C++库呢?
用Fortran的话,得自己造轮子还未必好用
您需要登录后才可以回帖 登录 | 极速注册

本版积分规则

捐赠本站|Archiver|关于我们 About Us|小黑屋|Fcode ( 京ICP备18005632-2号 )

GMT+8, 2024-11-23 02:50

Powered by Tencent X3.4

© 2013-2024 Tencent

快速回复 返回顶部 返回列表