Использование ALLOCATE и ошибки SegFault - PullRequest
0 голосов
/ 08 декабря 2011

Я компилирую код FORTRAN 90 с помощью компилятора gfortran (Ubuntu / Linaro 4.6.1-9ubuntu3) 4.6.1

После компиляции моего кода я получал ошибку Segmentation Fault, когда пытался запустить программу. После использования Valgrind я смог найти проблему в следующем разделе кода. Как можно видеть, DEALLOCATE использовался без предшествующего ALLOCATE. Я должен отметить, что я не тот, кто написал это программное обеспечение, и оно было успешно скомпилировано с использованием f90, однако у меня больше нет доступа к исходному компьютеру, на котором он был написан / скомпилирован.

   CONTAINS

  !! NewSiteType --------------------------------------------------------------------------
  ---
  !!
  !!- Searches for the index of a particular atom label
  !!
  FUNCTION NewSiteType(top,name,mass)

    IMPLICIT NONE

     !-------- function parameters ----------------

    INTEGER :: NewSiteType

    TYPE(TTopology), INTENT(INOUT) :: top
    CHARACTER(*),    INTENT(IN)    :: name
    REAL*8,          INTENT(IN)    :: mass

    !-------- local variables --------------------

    TYPE(TSiteType), DIMENSION(SIZE(top%siteTypes)+1) :: tmp
    INTEGER :: i



    NewSiteType = 0

    ! check if a site type was already registered

    DO i = 1,SIZE(top%siteTypes)
       IF (top%siteTypes(i)%name == name) THEN
          NewSiteType = i
          RETURN
       END IF
    END DO

    ! no, enlarge the list by the current one

! adding in an ALLOCATE to address a segfault problem hopefully
    ALLOCATE(top%siteTypes(SIZE(tmp)))

    tmp(1:SIZE(top%siteTypes)) = top%siteTypes
    DEALLOCATE(top%siteTypes)
    ALLOCATE(top%siteTypes(SIZE(tmp)))
    top%siteTypes = tmp
    top%siteTypes(SIZE(top%siteTypes)) = TSiteType(name,mass)
    NewSiteType = SIZE(top%siteTypes)

  END FUNCTION NewSiteType

Чтобы исправить проблему, я добавил строки

ALLOCATE(top%siteTypes(SIZE(tmp)))

Это исправило проблему Segfault, однако теперь эта функция не работает должным образом. Он предназначен для ввода и поиска в массиве, и, если ввод не в массиве, добавьте его. Однако теперь, когда я добавил исходный ALLOCATE, он, кажется, не добавляет незарегистрированные входные данные в массив, как предполагалось. Я думаю, что это потому, что есть конкретная ошибка, которая генерируется, когда программа пытается использовать сайты, которые не были зарегистрированы. И так как это единственное изменение, которое я сделал, я предполагаю, что просто делаю что-то неправильно, добавляя ALLOCATE.

Я хочу упомянуть одну вещь. Когда я запускаю Valgrind изначально, чтобы найти проблему с памятью, на самом деле кажется, что он запускает весь исполняемый файл как надо? Это кажется странным для меня.

1 Ответ

3 голосов
/ 08 декабря 2011

Последовательность строк

ALLOCATE(top%siteTypes(SIZE(tmp)))

    tmp(1:SIZE(top%siteTypes)) = top%siteTypes

не имеет смысла.Первый резервирует память для top% siteTypes, а второй использует содержимое этой памяти благодаря наличию переменной в RHS назначения, но переменная не была инициализирована.Расположение оператора allocate там, где он есть, не устранит проблему, связанную с тем, что переменная не выделяется, поскольку она использовалась выше.

Проблема может быть вне этой функции, которая, очевидно, предполагает, что top% siteTypes выделен и инициализирован,Намерение «inout» предполагает, что переменная top предназначена для ввода (и вывода), в то время как выделение при вводе удалит содержимое переменной, так что она станет фактически только выходной.Вы можете проверить, не были ли выделены с помощью "if (.not. Allocate (top% siteTypes)) ..."

...