使用ALLOCATE和SegFault错误

时间:2011-12-07 23:15:38

标签: memory-management segmentation-fault fortran

我正在使用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以找到内存的问题时,它实际上似乎运行整个可执行文件应该如此?这对我来说似乎很奇怪。

1 个答案:

答案 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))检查未分配的内容......”