在fortran中分配嵌套派生类型

时间:2017-12-13 07:26:57

标签: fortran

我正在尝试使用Ubuntu 16.04LTS下的gfortran 7.2编译此代码。

编译会发出警告Warning: ‘unknowns.28.var’ may be used uninitialized in this function [-Wmaybe-uninitialized]

当我尝试运行样品时 得到Segmentation fault - invalid memory reference.引用此语句allocate(x%p(i)%vars(kount),stat=ierr)

module fmod

implicit none

type  unknowns
      character , allocatable :: var
      integer , allocatable ::  exponent
end type unknowns
type term
      real , allocatable ::coeff
      integer, allocatable :: nounknowns
      type(unknowns) , allocatable :: vars(:) 
end type
type poly
      integer , allocatable :: noterms
      integer , allocatable :: nounknowns
      integer , allocatable :: mdegree
      type(term) , allocatable :: p(:)
end type poly

save

contains


  subroutine Allocate_polynomial(x,noofterms)
      type(poly) , allocatable:: x
      integer noofterms
      integer countterms
      integer i
      integer j
      integer kount

      integer ierr
      countterms = noofterms
      allocate(x,stat=ierr)
      IF (ierr/=0) THEN
          write(*,*) ' Could not allocate polynomial structure : error code=', ierr
          stop
      end if
      allocate(x%mdegree,stat=ierr)
      IF (ierr/=0) THEN
          write(*,*) ' Could not allocate mdegree : error code=', ierr
          stop
      end if
      allocate(x%nounknowns,stat=ierr)
      IF (ierr/=0) THEN
          write(*,*) ' Could not allocate nounknowns : error code=', ierr
          stop
      end if
      allocate(x%noterms,stat=ierr)
      IF (ierr/=0) THEN
          write(*,*) ' Could not allocate noterms : error code=', ierr
          stop
      end if
      allocate(x%p(countterms),stat=ierr)
      IF (ierr/=0) THEN
          write(*,*) ' Could not allocate array P : error code=', ierr
          stop
      end if
      kount = 10
      do i = 1, countterms
          allocate(x%p(i)%vars(kount),stat=ierr)
          IF (ierr/=0) THEN
             write(*,*) ' Could not allocate P(',I,').vars(10) : error code=', ierr
             stop
          end if
          allocate(x%p(i)%coeff,stat=ierr)
          IF (ierr/=0) THEN
             write(*,*) ' Could not allocate P(',I,').coeff : error code=', ierr
             stop
          end if
          allocate(x%p(i)%nounknowns,stat=ierr) 
          IF (ierr/=0) THEN
             write(*,*) ' Could not allocate P(',I,').nounknowns : error code=', ierr
             stop
          end if
          do j=1,kount
              allocate(x%p(i)%vars(j)%var,stat=ierr)
              x%p(i)%vars(j)%var = ' '
              allocate(x%p(i)%vars(j)%exponent,stat=ierr)
              IF (ierr/=0) THEN
                 write(*,*) ' Could not allocate P(',I,').vars(',j,').exponent : error code=', ierr
                 stop
              end if
              x%p(i)%vars(j)%exponent = 0
          end do
      end do

  end subroutine

  subroutine DeAllocate_Polynomial(x,noofterms)
      type(poly) , allocatable :: x
      integer noofterms

      integer i
      integer j
      do i = 1, noofterms
          do j=1,10
              deallocate(x%p(i)%vars(j)%var)
              deallocate(x%p(i)%vars(j)%exponent)
          end do
          deallocate(x%p(i)%coeff)   
          deallocate(x%p(i)%vars) 
          deallocate(x%p(i)%nounknowns) 
      end do
      deallocate(x%p) 

      deallocate(x%noterms)

      deallocate(x%nounknowns)

      deallocate(x%mdegree)
      deallocate(x)

  end subroutine

END MODULE fmod



Program PolyAlgebra
use fmod
implicit none
type(poly) , allocatable  :: x

integer noofterms
integer ierr

noofterms = 5

call allocate_polynomial(x,noofterms)
call DeAllocate_polynomial(x,noofterms)    
END

2 个答案:

答案 0 :(得分:2)

听起来像gfortran中的一个bug高达7.2,因为问题来自于包含可分配字符的某种类型的对象分配。以下代码与segfault崩溃:

program test
implicit none
type my
  character, allocatable :: var
end type my
type(my) , allocatable  :: x

allocate(x)

end

如果你使用指针代替它:

program test
implicit none
type my
  character, pointer :: var
end type my
type(my) , allocatable  :: x

allocate(x)

end

ifort 16没有此问题

修改

deferred-length字符变量的可分配也适用于gfortran 7.2(在4.9以下的版本中不支持):

program test
implicit none
type my
  character(:), allocatable :: var
end type my
type(my) , allocatable  :: x

allocate(x)

end

答案 1 :(得分:1)

感谢您的领导 我通过进行以下修改来实现它:

type  unknowns
          character(:) , allocatable :: var
          integer , allocatable ::  exponent
end type unknowns

allocate(character(len=1)::x%p(i)%vars(j)%var,stat=ierr)

编译并成功运行