fortran错误不正确:已分配可分配数组; DEALLOCATE指向无法解除分配的数组

时间:2015-05-06 14:31:09

标签: fortran

我写了一个以我不理解的方式失败的fortran代码。我试图在下面清楚地解释这个情景,但请让我澄清是否不清楚。

代码包含子程序

SUBROUTINE TMGP(NSYM,NOB,NFT,DEN,ncod,PR,np,lden,NPMX,nuccen,mdel)

IMPLICIT NONE
...
INTEGER :: NINTS
REAL(KIND=wp), ALLOCATABLE :: XBUF(:)
...

print *,"xbuf allocated ?",allocated(xbuf)
print *,"xbuf not allocated ?",.not.allocated(xbuf)

if (allocated(xbuf)) then 
    DEALLOCATE(xbuf)
end if

if (.not.allocated(xbuf)) then
    allocate (xbuf(nints))
end if

...

RETURN

END SUBROUTINE TMGP

然而,当我运行这个程序时,它就失败了:

DEALLOCATE(xbuf)

错误

forrtl: severe (173): A pointer passed to DEALLOCATE points to an array that cannot be deallocated

输出:

xbuf allocated ? T
xbuf not allocated ? F

如果我将代码更改为(并且除了添加此行之外不做任何其他更改):

print *,"xbuf allocated ?",allocated(xbuf)
print *,"xbuf not allocated ?",.not.allocated(xbuf)
print *,"nints = ",nints

if (allocated(xbuf)) then 
    DEALLOCATE(xbuf)
end if

if (.not.allocated(xbuf)) then
    allocate (xbuf(nints))
end if

然后运行这个程序就行了:

allocate (xbuf(nints))

我收到了消息:

forrtl: severe (151): allocatable array is already allocated

输出:

xbuf allocated ? F
xbuf not allocated ? T
nints =                      1

我对此感到非常困惑,因为在我看来,我使用的if语句应该使这种问题变得不可能,并且遵循代码的逻辑,这些错误是不可能的。

我正在使用ifort编译器,关于可能导致此问题的任何想法或有关如何修复它的建议将非常感激。

如果有任何其他信息有用,请与我们联系。

詹姆斯

1 个答案:

答案 0 :(得分:2)

您的观察结果可能是内部描述符损坏的结果,编译器使用该内部描述符来跟踪可分配(或指针)对象的状态,与特定编译器存储和测试对象分配状态的方式进行交互

这是特定编译器的非常多的实现细节,但至少有两种方式可以分配""对象的状态存储在对象的描述符中 - 支持对象的实际数据的非空机器地址,以及描述符中设置的单独标志。分配的内在函数正在查看这些信息之一,而对ALLOCATE语句的运行时支持正在查看另一个。通常这两条信息是一致的,但面对记忆腐败,你会看到明显的矛盾。可以在https://software.intel.com/en-us/node/525356找到当前版本的英特尔Fortran描述符布局的文档。

(另一个标志跟踪描述符是否用于可以解除分配的东西(即它是由ALLOCATE或类似的东西创建的)或不是(可能描述符用于引用另一个数组的一部分的指针) - 腐败标志结果" ...数组无法解除分配"消息。)

内存损坏可能是由程序中的错误引起的,该错误可能不在数组声明和使用的直接源位置。正如其他人在评论中所建议的那样 - 去寻找代码中的编程错误,例如数组下标超出界限或参数列表中的不匹配。编译器的运行时诊断选项通常会有所帮助。通过适当的调试功能,您还可以监视相关数组描述符的内存存储,并确定何时首先出现描述符状态的不一致。