Ошибка сегментации, связанная с компонентом производного типа - PullRequest
0 голосов
/ 24 августа 2018

Как видно из заголовка, я получаю ошибку сегмента, связанную с использованием компонента производного типа.Это продолжение ошибки сегментации для массива, но только если компонент производного типа , но представляет более реалистичный вариант использования.В отличие от предыдущего вопроса, нет проблемы отсутствия явного интерфейса (приведенный ниже пример представляет собой одну программу без подпрограмм, и результаты те же, если программа модульная в более реалистичном сценарии использования).

! gfortran 4.8.5 on Red Hat linux
! default compile with no extra flags:  "gfortran source.f90"
! default stack size = 8mb (ulimit -s)

program main

    type table
        real :: col(2100000) = 0.0         ! but OK if no initial value
    end type table

    type(table) :: table1(2)               ! but OK if not an array

    table1(1)%col = 1.0                    ! segfault here

end program main

В более реалистичном варианте использования (и в моем настоящем) тип table будет определен в модуле, я просто собрал все это в одном месте для краткости.(Я проверял это таким образом (с определением типа в модуле), и произошла точно такая же ошибка сегмента.)

Здесь есть как минимум 3 изменения, которые устраняют ошибку сегмента (только последнее из которых работает оченьхорошо для моих целей)

  1. Не инициализировать тип
  2. Не объявлять table1 как массив
  3. Сделать компонент col размещаемым

Ключ (и самое удивительное для меня), кажется, заключается в том, что он объявляет table1 как массив, который, похоже, каким-то образом обманывает компилятор.Кроме того, наличие компонента производного типа является существенным аспектом.

Для ответа я просто ищу общее объяснение того, что здесь происходит (в том числе, если это какая-то ошибка) и общие рекомендации.об избежании этой проблемы - в частности, каковы наилучшие методы, которым следует следовать, которые, надеюсь, помогут мне избежать этой проблемы.

Обратите внимание, что эта проблема частично относится к размеру стека (например, ulimit -s) ивзаимодействие с оболочкой, но в ответе на предыдущий вопрос этот вопрос рассматривается довольно хорошо, и я надеюсь изучить здесь другие аспекты проблемы, которая не сводит эту проблему к минимуму, а скорее включает и другие аспекты.

Редактировать, чтобы добавить: @Steve отмечает, что "Это не имеет абсолютно никакого отношения к Fortran, не говоря уже о gfortran".Это, возможно, суть моего вопроса.Я ожидаю, что компилятор фортрана сможет обрабатывать чисто статические объявления, как я использую здесь, но, возможно, я ожидаю слишком многого.Является ли проблема с корнем несовпадением среды (например, ulimit -s (8mb)) и флагами компилятора?Разве компиляторы (gfortran или другие) не имеют возможности запрашивать окружение или вычислять это автоматически?

Я ценю в ответе @ ripero на вопрос предшественника, что увеличение размера стека может быть полезным, хотя это несколько неполно для меняв том смысле, что проблема может заключаться не в размере стека, а в некотором несовпадении между размером стека (проблема уровня ОС или среды) и такими параметрами компилятора, как -fmax-stack-var-size?

...