I have defined the following derived type in Fortran:
type :: derived_type
logical :: is_allocated = .false.
integer :: n_layer = 0
integer :: type = 0
real, allocatable :: radius(:)
end type derived_type
I then define a variable with this derived type in a subroutine:
type(derived_type), intent(inout) :: sphere(15)
However, when I try to call sphere(1)%type
, such as through print
, later in the subroutine, I receive a segmentation fault error instead of the expected 0
. I have tried renaming type
to some other name because I was thinking that type
might be a reserved name, but it still returns a segmentation fault. Weirdly enough, sphere(1)%is_allocated
is defined and it returns .false.
. I tried moving the integer :: type = 0
at the top of the list and it returns the correct value, but calling the other parameters return a segmentation fault.
I am not an expert in Fortran and I don't know what could be the problem here? I am using gfortran 9.4.0 in compiling the script.
The code itself is part of a bigger script and the error log seems to point to a part similar to what I mentioned.
Update
Here is a minimal reproducible example.
shape_type.mod
module shape_type
type :: shape_params
logical :: is_allocated = .false.
integer :: type = 0
real(8), allocatable :: perimeter(:)
end type shape_params
end module shape_type
shape_list.mod
module shape_list
use shape_type, only: shape_params
type :: shape_list_params
logical :: is_allocated = .false.
type(shape_params), allocatable :: geometry(:)
end type shape_list_params
end module shape_list
test_subroutine.f90
subroutine test_subroutine(geometry)
use shape_type, only: shape_params
implicit none
type(shape_params), intent(inout) :: geometry(15)
print *, geometry(1)%is_allocated
print *, geometry(1)%type
end subroutine test_subroutine
main_program.f90
program main_program
use shape_list, only: shape_list_params
implicit none
type(shape_list_params), save, dimension(1) :: form
call test_subroutine(form(1)%geometry)
end program
You need to allocate all variables which have the allocatable
attribute explicitly. This will not be done by the Fortran compiler automatically, you have to care for it yourself: Allocatable Arrays.
Your program works after allocating the variable with allocate()
like this:
program main_program
use shape_list, only: shape_list_params
implicit none
type(shape_list_params), save, dimension(1) :: form
allocate(form(1)%geometry(15)) ! allocation added
call test_subroutine(form(1)%geometry)
end program
Some comments:
allocatable
for which you need to care: real(8), allocatable :: perimeter(:)
. You either need to allocate this also, or since it is only a single value, you could remove the attribute.is_allocated
. Better use Fortran's intrinsic allocated.save
attribute in your main program will not have any effect. It is useful only in subroutines and functions to keep the values of variables until the next call..f90
extension. But that is most probably only a copy and paste error.