2011-12-07 59 views
0

我使用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))) 

然而,这固定内存设计缺陷的问题,现在这个功能不能正常工作。它旨在输入和搜索数组,如果输入不在数组中,请添加它。但是,现在我已经添加了初始ALLOCATE,它似乎不会将未注册的输入添加到数组中,因为它应该是。我认为这是因为程序尝试使用尚未注册的网站时会生成一个特定的错误。由于这是我做出的唯一改变,我猜测我只是通过添加ALLOCATE来做一些不正确的事情。

我确实想提一件事。当我运行Valgrind最初发现内存的问题时,它实际上似乎会运行整个可执行文件,因为它应该如此?这对我来说似乎很奇怪。

回答

3

线

ALLOCATE(top%siteTypes(SIZE(tmp))) 

    tmp(1:SIZE(top%siteTypes)) = top%siteTypes 

没有意义的序列。第一个预留内存用于顶级%siteType,第二个通过在分配的RHS上具有变量来使用该内存的内容,但该变量尚未初始化。找到你拥有它的分配语句不会解决上面使用的变量未被分配的问题。

这个问题可能在这个函数之外,这显然假定顶级%siteTypes被分配和初始化。 “inout”的意图表明变量top意在被输入(和输出),而在输入时分配会擦除变量的内容,因此它只能被有效地输出。你可以通过“if(.not。allocated(top%siteTypes))...”来检查未被分配...“