Ahmad H.
Ahmad H.

Reputation: 33

Allocation of nested derived types in fortran

I am trying to compile this code using gfortran 7.2 under Ubuntu 16.04LTS.

The compile gives a warning Warning: ‘unknowns.28.var’ may be used uninitialized in this function [-Wmaybe-uninitialized].

When I attempt to run the sample I get a Segmentation fault - invalid memory reference. referencing this statement 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

Upvotes: 2

Views: 713

Answers (2)

IgorM
IgorM

Reputation: 307

Sounds like a bug in gfortran up to 7.2 as the problem comes form object allocation of some type containing a character allocatable. The following code crashes with segfault:

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

allocate(x)

end

It works if you use pointer instead:

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

allocate(x)

end

ifort 16 doesn't have this problem

EDIT:

Allocatable of deferred-length character variable also works with gfortran 7.2 (it is not supported in versions up to 4.9):

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

allocate(x)

end

Upvotes: 2

Ahmad H.
Ahmad H.

Reputation: 33

Thank you for the lead.
I got it working by making the following modifications:

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

and

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

and that compiled and ran successfully

Upvotes: 1

Related Questions