Search code examples
arraysstringfortransegmentation-faultallocation

Segfault with allocated string array in Fortran


I am trying to loop over all arguments passed to a Fortran program, with the number of arguments varying. Thus I made the array of strings allocatable.

However once I to start said loop, I get a segfault, if any argument is given.

Is there any problem with having an allocatable string array?

CODE:

program read_args

implicit none
character(len=999), allocatable :: args(:)
integer, allocatable :: i, nargs

nargs=command_argument_count()

if ( nargs == 0 ) then
    print*, 'err: no arguments or options'
    stop
end if

allocate(args(1:nargs))

print*, nargs, size(args(:))
do i=1,nargs
    call getarg(i,args(i))
    args(i)=trim(adjustl(args(i)))
end do

end program

The number of arguments and array size is printed, once I try to read in the argument, I get a segfault.

Compiler, gfortran - gcc , v8.3.0 on debian 10

(To avoid XY-problems: the idea is to check for option flags in the argument list as well as to get all file names which should be processed)

Results:

$ ./a.out
err: no arguments or options

$ ./a.out arg1 arg2
2  2
<Segfault>

Solution

  • As the comments have stated, the problem in this program is the use of the unallocated variable i in the do construct, not the use of the the character array inside the construct.

    We can be precise about why this use of i is problematic.

    In

    do i=1,nargs
    

    we have that i is the "do variable" (Fortran 2018, 11.1.7.2). In such a do construct we know (Fortran 2018, 11.1.7.4.1) that as part of the processing of the loop:

    The DO variable becomes defined with the value of the initial parameter

    So, does this "definition" involve first an allocation of i?

    It does not. This contrasts with the explicit allocation process as part of intrinsic assignment, say (such as with the valid nargs=command_argument_count()). This "becomes defined" is not allowed with i not allocated (Fortran 2018, 5.4.10):

    An unallocated allocatable variable shall not be referenced or defined.

    The definition of i is not the same process as having i the target of an intrinsic assignment with the initial parameter.

    In general, having allocatable scalars such as i and nargs can be useful, but in the case of this question that doesn't appear so: removing the allocatable attribute from them doesn't change the logic. Alternatively, i can be explicitly allocated (without needing to give it a value) before the do construct is entered.