Matyas
Matyas

Reputation: 654

fortran pointer array as return

I am looking at a Fortran function that returns an array (of pointers) to fixed length strings. Something like this:

FUNCTION F(N)
INTEGER :: N
CHARACTER(LEN=16) :: F(N)

F(1:N) = 'DEFAULT'
...
END FUNCTION F

The function computes N strings and to my understanding tries to return these strings in an array.

The caller has:

...
ALLOCATE(X(N))
X = F(N)

However I get a segfault when F returns. The author claims he does not see any issues when he compiles and runs it. I am trying to understand when the memory gets allocated for the actual strings and whether the memory is in scope after return? Does the

CHARACTER(LEN=16) :: F(N)

line allocate N*16 characters and then N pointers pointing to them in F? I am coming from C so maybe I am missing this completely, please be gentle. I suspected that the actual pointed to memory by F is not bound after the return (I thought that it could be on the stack etc.)

Any insight is appreciated.

Upvotes: 2

Views: 961

Answers (1)

casey
casey

Reputation: 6915

Your function doesn't return an array of pointers, it returns an array of characters of length 16. You may be assigning the return value to a pointer or allocatable variable of a rank 1 array character(len=16), but that is a separate issue.

A function returning an array needs an explicit interface. It isn't clear from your question if this requirement has been met and this can be accomplished three ways:

  1. put the function in a module (easiest!)
  2. put the function in the main program after a contains statement
  3. write an interface block for the function in the scoping unit is used in.

For example:

module A
contains
  function f(n)
    implicit none
    integer :: n
    character(len=16) :: f(n)

    f(1:n) = 'DEFAULT'
  end function f
end module A

program test
  use A
  implicit none
  character(len=16), pointer :: array(:)

  allocate(array(10))
  array = f(10)

  print *, array
end program test

This puts your function within module 'A' as is with slight the addition of implicit none statement, which you should be using. Unlike C, Fortran will let you use variables without declaring them and implicitly assign types to them, which rears its ugly head when a typo creates a new variable and a debugging nightmare. implicit none tells the compiler to only use variables you declare.

The main program in the example above stores the return value of function in a pointer to a character array. The return value is not simply N*16 bytes because, unlike C, Fortran strings contain some metadata, including the length (and are not null terminated). The array itself will have an array descriptor internally that stores information on the array bounds, dimensions and some other information, so the overall allocation will be for at least N*(16+character scalar overhead)+array descriptor length. A bit more is going on under the hood than in C.

A last point to note, the variable f of the same name of the funtion f is the type of the function and its return value. This will be in scope when the function returns and the memory will be copied into the allocated memory of array. A final potential issue you might run into as a C programmer is that Fortran passes arguments by reference. This isn't an issue here, but later on this might crop up if you assumed pass by value like C does.

Upvotes: 1

Related Questions