Утечка памяти при возврате выделенных строк - PullRequest
2 голосов
/ 08 марта 2019

Предлагаемое решение для возврата строки переменной длины в Фортране было из этого вопроса:

  function itoa(i) result(res)
    character(:),allocatable :: res
    integer,intent(in) :: i
    character(range(i)+2) :: tmp
    write(tmp,'(i0)') i
    res = trim(tmp)
  end function

Правильно ли я понимаю, что результат этой функции никогда не освобождается?Так что для больших чисел и большого количества вызовов вы можете столкнуться с утечками памяти.

Так что я имею в виду именно тот случай, когда я не назначаю результат своей функции, а использую его «На месте» какв

do i = 1, n
    write(*, *) "tmp_"//itoa(i)
end do

у меня явно нет ссылок на результат, по которому я мог бы позвонить deallocate, и пока я зацикливаюсь, он определенно не выходит за рамки.

Если я понимаюВы (@Francescalus) правильно, я все еще могу рассчитывать на то, что он освобожден.

Ответы [ 2 ]

2 голосов
/ 08 марта 2019

Этот вопрос является частным случаем этого другого , но, будучи конкретным, он позволяет нам быть более точным. Вы должны прочитать ответы там для более общих деталей.

В правильной реализации не ожидается утечки памяти. Стандарт Фортрана обращается к этим результатам явно. Например, в Fortran 2008 в примечании 12.41 говорится:

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

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

Итак, память может «просочиться» на некоторое время, но следует ожидать исправления довольно быстро. Множество уровней оценки функций могут вызывать проблемы - но вы, вероятно, получили неприятный код задолго до этого.

1 голос
/ 08 марта 2019

Вы правы только в том, что результат никогда не освобождается, если ваш код никогда не освобождает его, или, возможно, более уместен, если он никогда не выходит из области видимости.Но утечка памяти происходит только тогда, когда вы теряете последнюю ссылку на выделенную память, и на самом деле это довольно сложно сделать в современном Фортране, особенно для распределенных переменных, но немного проще с указателями.

Если переменная выделена в рамках другой подпрограммы, она будет получена операционной системой (потому что это то, что должно произойти в стандарте Фортрана), когда подпрограмма завершится.И если он находится в области действия программы и никогда не освобождается, это не утечка памяти.

...