我正在使用gfortran编译器编译一些FORTRAN 90代码(Ubuntu / Linaro 4.6.1-9ubuntu3)4.6.1
编译我的代码后,当我尝试运行程序时,我收到了分段错误错误。使用Valgrind后,我能够在下面的代码部分找到问题。可以看出,正在使用DEALLOCATE而没有先前的ALLOCATE。我应该注意到,我不是那个编写这个软件的人,而且它是用f90成功编译的,但是我不再能够访问这个编写/编译过的原始机器了。
CONTAINS
!! NewSiteType --------------------------------------------------------------------------
---
!!
!!- Searches for the index of a particular atom label
!!
FUNCTION NewSiteType(top,name,mass)
IMPLICIT NONE
!-------- function parameters ----------------
INTEGER :: NewSiteType
TYPE(TTopology), INTENT(INOUT) :: top
CHARACTER(*), INTENT(IN) :: name
REAL*8, INTENT(IN) :: mass
!-------- local variables --------------------
TYPE(TSiteType), DIMENSION(SIZE(top%siteTypes)+1) :: tmp
INTEGER :: i
NewSiteType = 0
! check if a site type was already registered
DO i = 1,SIZE(top%siteTypes)
IF (top%siteTypes(i)%name == name) THEN
NewSiteType = i
RETURN
END IF
END DO
! no, enlarge the list by the current one
! adding in an ALLOCATE to address a segfault problem hopefully
ALLOCATE(top%siteTypes(SIZE(tmp)))
tmp(1:SIZE(top%siteTypes)) = top%siteTypes
DEALLOCATE(top%siteTypes)
ALLOCATE(top%siteTypes(SIZE(tmp)))
top%siteTypes = tmp
top%siteTypes(SIZE(top%siteTypes)) = TSiteType(name,mass)
NewSiteType = SIZE(top%siteTypes)
END FUNCTION NewSiteType
要解决问题,我添加了行
ALLOCATE(top%siteTypes(SIZE(tmp)))
这解决了Segfault问题但是现在这个功能无法正常工作。它旨在获取输入并搜索数组,如果输入不在数组中,则添加它。但是,现在我已经添加了初始ALLOCATE,它似乎没有按照预期将未注册的输入添加到数组中。我认为这是因为当程序尝试使用尚未注册的站点时会产生特定错误。因为这是我所做的唯一改变,我猜我只是通过添加ALLOCATE做错了。
我想提一件事。当我最初运行Valgrind以找到内存的问题时,它实际上似乎运行整个可执行文件应该如此?这对我来说似乎很奇怪。
答案 0 :(得分:3)
行序列
ALLOCATE(top%siteTypes(SIZE(tmp)))
tmp(1:SIZE(top%siteTypes)) = top%siteTypes
没有意义。第一个为top%siteTypes保留内存,第二个通过在赋值的RHS上使用变量来使用该内存的内容,但该变量尚未初始化。在您拥有它的位置找到allocate语句不会解决自上面使用以来未分配的变量的问题。
问题可能在此函数之外,显然假设已分配和初始化top%siteTypes。 “inout”的意图表明变量top意图是输入(和输出),而在输入时分配将擦除变量的内容,因此它实际上只是输出。您可以通过“if(.not.distributed(top%siteTypes))检查未分配的内容......”