Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Fortran 释放模块中声明的变量时出错_Fortran_Fortran90_Memory Management - Fatal编程技术网

Fortran 释放模块中声明的变量时出错

Fortran 释放模块中声明的变量时出错,fortran,fortran90,memory-management,Fortran,Fortran90,Memory Management,我的Fortran 90代码有一个问题,涉及到释放一个数组,该数组在模块中声明,然后在子例程中分配和初始化。在我的程序中,我在模块中声明了一组数组,如real*8,dimension(:),allocatable::test。然后,在初始化子程序中,我使用模块,分配变量 分配(测试(8)),并使用test=0.d0对其进行初始化 在此之后,我可以打印*,测试,并获得适当的输出:0.E+0.E+0.E+0.E+0.E+0.E+0.E+0.E+0.E+0.E+0.E+0。此外,调用allocated

我的Fortran 90代码有一个问题,涉及到释放一个数组,该数组在模块中声明,然后在子例程中分配和初始化。在我的程序中,我在模块中声明了一组数组,如
real*8,dimension(:),allocatable::test
。然后,在初始化子程序中,我使用模块,分配变量
分配(测试(8))
,并使用
test=0.d0对其进行初始化

在此之后,我可以
打印*,测试
,并获得适当的输出:
0.E+0.E+0.E+0.E+0.E+0.E+0.E+0.E+0.E+0.E+0.E+0
。此外,调用
allocated(test)
将返回
.TRUE.
。然而,有些地方出了问题。在调用
allocate()
之后,调用
sizeof(test)
返回
0
,调用
deallocate(test)
抛出以下错误:

lib-4422 : UNRECOVERABLE library error 
  A DEALLOCATE statement argument points to a portion of the
 original allocation.
  Original size in bytes for the argument is 512
  Current size in bytes for the argument is 0
Segmentation fault
这一切都发生在一个更大的代码中,在整个代码中,我使用了这些数组,没有任何错误。我只是在寻找内存泄漏时,试图在程序结束时释放内存时才注意到这个问题。我试图制作一个简单的程序,只执行上面描述的操作(即,在模块中声明,在子例程中分配和初始化,然后打印数组并在同一子例程中取消分配)。然而,这段简单的代码工作正常,运行时不会出错。因此,我对在更大的代码上下文中是什么导致这种行为不当感到非常困惑。此外,如果在我的大代码中,我将声明行从模块移动到子例程,那么一切都会正常运行

任何建议都将不胜感激!提前感谢,


~BCL

当处理非单个子例程内部的数组时,我总是在声明它们时使用
指针
属性,而不是属性。在实践中,两者的作用是相同的。例如:

module Mod1
contains
  subroutine sub1(Array)
    !*** Declaration of Variables
    implicit none
    !*** External Variables - Arguments
    real(kind=8), pointer, intent(inout) :: Array(:)
    !*** Internal Variables
    real(kind=8), allocatable            :: InternalArr(:)
    !*** Memory allocation
    allocate(Array(1:8))
    allocate(InternalArr(9:10))
    !*** End of Subroutine
  end subroutine sub1
end module Mod1
调用
sub1
后,数组将在代码的任何位置保留其维度。您可以根据需要
解除分配
分配

在使用
指针
之前,我遇到了一些问题,比如您描述的问题,有人建议我改用
指针
。从那时起,我就非常习惯于用这种方式声明数组(如果它们要保留在我一直使用的
可分配的
的同一子例程或模块上),而且它一直被证明是控制数组的好方法

我真的希望这有帮助。。。这是我的第一个答案:)
编辑:我更正了示例代码中的一个小错误

注意
sizeof
(供应商扩展名)和
size
(fortran内部版本)是不同的。听起来你的程序有一些错误的部分破坏了内存。现在是使用常规调试技术的时候了(使用完整的调试选项进行编译,使用静态和动态代码正确性工具,开始二分法以隔离代码中有问题的部分)。你是说,在没有任何代码干预的情况下,先进行分配、sizeof,然后再取消分配?那么,解除分配的失败是非常奇怪的。如果存在中间代码,那么显然要查看该代码。根据IanH的建议,启用所有调试选项,特别是运行时下标(边界)检查。确保您的过程在模块中,以便检查参数的一致性。我的建议是相反的:使用
可分配的
变量,除非您必须使用
指针
变量,因为您无法使用
可分配的
来完成任务<代码>可分配
变量更安全,因为不可能发生内存泄漏。我知道这两个讨论,我也同意你的看法,因为一个“可分配”数组在内存方面是连续的,所以“可分配”更有效。但是,正确分配和释放内存将防止内存泄漏。事实上,我取消分配“可分配”数组,就好像它们是“指针”一样。不过我想这是个人喜好的问题。无论如何,我只是建议使用“指针”作为提示,因为它们在fortran90中更通用。但是我相信一个更有经验的fortran程序员会给出一个更好的解决方案