Function returning null pointer: is it usable in practice?

Assume I want to create an array that contains a chunk of another array and I want to use a pointer to avoid copying data: if my function returns null, I get a segfault with gfortran, while ifort and ifx both work. What does the standard say about this edge case? My understanding is that it is illegal to feed a null pointer to another routine, but the intrinsic functions should work?

program test_null
     integer, allocatable :: i(:)
     integer, pointer :: p(:)

     i = [1,2,3,4,5,6,7,8,9,10]

    ! Returns actual chunk
     print *, count(mod(point_to_i(i,2,5),2)==0)

     ! Segfault: null pointer in intrinsic
     print *, count(mod(point_to_i(i,20,5),2)==0)


     contains

       function point_to_i(i,i1,i2) result(ptr)
           integer, intent(in), target :: i(:)
           integer, intent(in) :: i1,i2
           integer, pointer :: ptr(:)

           if (i2>=i1 .and. min(i1,i2)>0 .and. max(i1,i2)<=size(i)) then
               ptr => i(i1:i2)
           else
               nullify(ptr)
           endif

       end function point_to_i

end program

An alternative would be to allocate the pointer to a 0-size array:

allocate(ptr(0))

but I’m not sure that would lead to a memory leak?

The reason I’m asking is that I have a derived type that I’d like to access several portions of an array it contains:


type, public :: mytype
   integer, allocatable :: long_array(:)
   contains
      procedure :: section1 => point_to_section1
      procedure :: section2 => point_to_section2
end type

You can also let your pointer point to an empty section. No need to allocate it:

p => array(2:1)

(not quite sure if this is legal if the array itself is empty or has only one element - array bounds?)

Awesome, thank you!

so, assuming the input array could be empty, does it make sense to point to the whole in that case?

           n = size(i)
           if (n<=0) then 
               ptr => i
           elseif (i2>=i1 .and. min(i1,i2)>0 .and. max(i1,i2)<=n) then
               ptr => i(i1:i2)
           else
               ptr => i(n:1)
           endif

Yes, it does look that way :slight_smile:

1 Like