Как видно из заголовка, я получаю ошибку сегмента, связанную с использованием компонента производного типа.Это продолжение ошибки сегментации для массива, но только если компонент производного типа , но представляет более реалистичный вариант использования.В отличие от предыдущего вопроса, нет проблемы отсутствия явного интерфейса (приведенный ниже пример представляет собой одну программу без подпрограмм, и результаты те же, если программа модульная в более реалистичном сценарии использования).
! 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 изменения, которые устраняют ошибку сегмента (только последнее из которых работает оченьхорошо для моих целей)
- Не инициализировать тип
- Не объявлять
table1
как массив - Сделать компонент
col
размещаемым
Ключ (и самое удивительное для меня), кажется, заключается в том, что он объявляет table1
как массив, который, похоже, каким-то образом обманывает компилятор.Кроме того, наличие компонента производного типа является существенным аспектом.
Для ответа я просто ищу общее объяснение того, что здесь происходит (в том числе, если это какая-то ошибка) и общие рекомендации.об избежании этой проблемы - в частности, каковы наилучшие методы, которым следует следовать, которые, надеюсь, помогут мне избежать этой проблемы.
Обратите внимание, что эта проблема частично относится к размеру стека (например, ulimit -s
) ивзаимодействие с оболочкой, но в ответе на предыдущий вопрос этот вопрос рассматривается довольно хорошо, и я надеюсь изучить здесь другие аспекты проблемы, которая не сводит эту проблему к минимуму, а скорее включает и другие аспекты.
Редактировать, чтобы добавить: @Steve отмечает, что "Это не имеет абсолютно никакого отношения к Fortran, не говоря уже о gfortran".Это, возможно, суть моего вопроса.Я ожидаю, что компилятор фортрана сможет обрабатывать чисто статические объявления, как я использую здесь, но, возможно, я ожидаю слишком многого.Является ли проблема с корнем несовпадением среды (например, ulimit -s (8mb)) и флагами компилятора?Разве компиляторы (gfortran или другие) не имеют возможности запрашивать окружение или вычислять это автоматически?
Я ценю в ответе @ ripero на вопрос предшественника, что увеличение размера стека может быть полезным, хотя это несколько неполно для меняв том смысле, что проблема может заключаться не в размере стека, а в некотором несовпадении между размером стека (проблема уровня ОС или среды) и такими параметрами компилятора, как -fmax-stack-var-size
?