9

I'm using gfortran -std=f2008. I have a function that returns a derived type which contains an allocatable array. The function calls allocate() before it returns. It seems like the array is being automatically deallocated some time after the function that allocated the array has returned, and my program segfaults.

When does automatic deallocation occur? Should I be coding this in a different way?

hertzsprung
  • 9,445
  • 4
  • 42
  • 77

2 Answers2

17

A universal answer: allocatable arrays are automatically deallocated when going out of scope. Function results are automatically deallocated after the result is "used" in the outer scope. Allocatable components are deallocated, when the parent derived type variable is going out of scope, or when it is deallocated.

Only pointers, that pointed to the function results are undefined after the deallocation and shall not be used. If you do that, it could cause the problems you describe.

Also, when an array is automatically reallocated on assignment, the pointers to it become undefined (but may not change, actually).

In other words, problems you describe shouldn't occur when the allocatables are used correctly.

  • So if I hold a non-pointer reference to a derived type that was returned by a function, and has an `allocatable` array component, that array will remain allocated? – hertzsprung Feb 26 '14 at 09:04
  • What is a "non-ponter" reference? When exactly you want it to remain allocated? The whole function result (including non-ponter components) is deallocated after the function value is used in an expression or assignment. – Vladimir F Героям слава Feb 26 '14 at 09:08
3

Another general advice : most of the time, it is much safer to use subroutines instead of functions for returning complicated results like arrays, pointers, derived types with allocatable inside...

Additional question : do you use your function within an expression ? If not then it should be a subroutine. Fortran functions have only interest if used within calculation expressions.

Francois Jacq
  • 1,244
  • 10
  • 18
  • 3
    Can you justify the assertions you make in this answer ? In what ways are subroutines *safer* than functions ? And I challenge you to illustrate the use of a function which is not *within an expression* – High Performance Mark Feb 04 '14 at 15:29
  • Because with a subroutine for instance, the returned value is usually an argument clearly identified in the calling routine. You don't depend on a function result you cannot manage easily. About a function which is not in an interesting expression : a=f(...). If the function is only used that way, I suggest instead "CALL f(...,a)". – Francois Jacq Feb 04 '14 at 15:45
  • A function returning a pointer is especially dangerous. Do you intent to use it with a=>f(...) or a=f(...) ? I have seen many mistakes with that. This is also true if the function returns an array. Imagine the result of a=>f(...). – Francois Jacq Feb 04 '14 at 15:51
  • I frequently use allocatable array valued functions in ifort 13 with no issues. – bdforbes Feb 05 '14 at 02:28
  • I use them also from time to time, especially through the form of operators. But about function returning large results (arrays or complicated derived types with allocatable or not), I met performance issues : using functions means creating intermediate objects to store its result (each time the function is invoked). – Francois Jacq Feb 05 '14 at 06:28
  • Are you sure a new array would be created? I thought with F2003 semantics, `a = func()` where `a` is `allocatable` and `func` returns an `allocatable` array, means that allocation of the return value within the function _actually_ allocates `a` in the parent scope. – bdforbes Feb 06 '14 at 01:18
  • 1
    @bdforbes By the rules of the language - no. In terms of *equivalent* *implementation* - maybe, if a compiler is **very** smart and there isn't the possibility of things like defined assignment and finalizers. There aren't many F2003 compilers. There are even less very smart F2003 compilers :(. But I still use functions with allocatable or derived type results all the time (not pointer functions). – IanH Feb 06 '14 at 07:00
  • I'll check it out on ifort and see what happens. – bdforbes Feb 06 '14 at 10:37
  • 1
    @HighPerformanceMark Here's a possibly obscure response to your challenge -- as of F2008 corrigendum three (soon?), a *variable* can be a *function-reference* that returns a data pointer result. There are a number of places that a variable can appear where an expression cannot - notably the left hand side of a assignment statement and in the input list in a read statement. (Before corrigendum three the syntax rules for a variable were more general, but that resulted in language syntax ambiguity.) – IanH Feb 06 '14 at 11:34
  • In `Intel(R) Visual Fortran Compiler XE 13.1.1.171`, there was no intermediate result for an `allocatable`-array-valued function, i.e. it was perfectly fine to return a big array from a function. Here is my test case: http://pastebin.com/7yZMVnw2 --- I used the default project settings in Visual Studio, with no optimisations, and not even using F2003 semantics. – bdforbes Feb 06 '14 at 21:57