Segfault с выделенным массивом строк в Фортране - PullRequest
3 голосов
/ 23 сентября 2019

Я пытаюсь перебрать все аргументы, переданные в программу на Фортране, с различным количеством аргументов.Таким образом, я сделал массив строк размещаемым.

Однако, как только я запускаю указанный цикл, я получаю segfault, если задан какой-либо аргумент.

Есть ли проблемы с наличием размещаемого массива строк?

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

Количество аргументов и размер массива печатаются, как только я пытаюсь прочитать аргумент, я получаю ошибку segfault.

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

(Чтобы избежать XY-проблем: идея состоит в том, чтобы проверить флаги опций в списке аргументов, а также получить все имена файлов, которые должны быть обработаны)

Результаты:

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

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

1 Ответ

4 голосов
/ 24 сентября 2019

Как отмечалось в комментариях, проблема в этой программе заключается в использовании нераспределенной переменной i в конструкции do, а не в использовании массива символов внутри конструкции.

Мы можем бытьточно о том, почему такое использование i проблематично.

В

do i=1,nargs

мы имеем, что i - это «переменная do» (Fortran 2018, 11.1.7.2).В такой конструкции do мы знаем (Fortran 2018, 11.1.7.4.1), что как часть обработки цикла:

Переменная DO становится определенной со значением начального параметра

Итак, включает ли это «определение» вначале распределение i?

Это не так.Это контрастирует с явным процессом выделения, как часть внутреннего присваивания, например (например, с действительным nargs=command_argument_count()).Это «становится определенным» не допускается, если i не выделено (Fortran 2018, 5.4.10):

На нераспределенную размещаемую переменную нельзя ссылаться или определять.

Определение i - это не то же самое, что определение i цели внутреннего присваивания с начальным параметром.

Как правило, наличие выделяемых скаляров, таких как i и nargsможет быть полезным, но в случае с этим вопросом это не так: удаление атрибута allocatable из них не меняет логику.В качестве альтернативы, i может быть выделено явно (без необходимости присваивать ему значение) перед вводом конструкции do.

...