2

I would like to create an array of pointers to arrays, which are dynamically allocated if/when my result is ready. The following code uses a type to get around being unable to set an array of pointers, but the function makeArray is always returning the same memory address.

The expected outcome would be different addressess, and thus separately controllable arrays. (I need to do this because I have very very large arrays that will be populated at random but must be ordered, and I don't want to preallocate a massive 2x2 array (order of 8GB) nor constantly reallocate and sort as new results come in, so my solution is preallocate a large 1x1 array that can have pointers to the 2nd dim, meaning I can place the pointer to the result in its correct "slot" if/when it becomes available)

module mymodule 
contains

function makeArray(size)
  integer :: size
  integer, target, allocatable :: a(:)
  integer, pointer :: makeArray(:)
  allocate(a(size))
  a = 0
  makeArray => a
  end function 
  end module mymodule

program test
  use mymodule
  implicit none
 
  type :: IntPointer
    integer, pointer :: ptr(:)
    integer :: id
  end type
  
  type(IntPointer), allocatable :: ptrarray(:)
  integer :: i

  
 allocate(ptrarray(5))
 ptrarray(1)%ptr => makeArray(1277)
  ptrarray(1)%id = 1
 ptrarray(2)%ptr => makeArray(13567)
  ptrarray(2)%id = 2

  ptrarray(1)%ptr(12) = 10

  do i=1, size(ptrarray)
  write(*,*) ptrarray(i)%id
  write(*,*) LOC(ptrarray(i)%ptr)
  end do


end program

Thanks

EDIT Solved, I'll keep this here for posterity: I suppose the crux of the issue is being able to allocate a 2d array where the 2nd dimension can vary significantly. The magic word I needed to look for was "Ragged Array" and it seems this post answers my question.

Luke
  • 23
  • 4
  • 2
    The usual question that needs to be asks is *Are you sure you want to pointers?* – steve May 26 '21 at 01:42
  • @steve I suppose the crux of the issue is being able to allocate a 2d array where the 2nd dimension can vary significantly. The magic word I needed to look for was "Ragged Array" and it seems [this](https://stackoverflow.com/questions/18316592/multidimensional-array-with-different-lengths) post answers my question – Luke May 26 '21 at 17:57
  • @Luke See also https://stackoverflow.com/questions/67697060/realize-an-array-which-the-second-dimension-depends-on-the-first-argument the term is also *jagged* array. – Vladimir F Героям слава May 26 '21 at 18:05

1 Answers1

1

When I used gfortran with sufficient debugging options, it gave the answer:

   10 |   makeArray => a
      |  1
Warning: Pointer at (1) in pointer assignment might outlive the pointer target [-Wtarget-lifetime]

Because a is an allocatable, when the function exits, it is automatically deallocated.

But if you try to fix that by adding save to the declaration of a, when you call the function makeArray a second time, the function will attempt to allocate an already allocated variable. Probably a new design without the intermediate a will work better. Or perhaps a different data structure than a sparsely populated array. Maybe a linked list?

M. S. B.
  • 28,968
  • 2
  • 46
  • 73
  • Thanks, how could I avoid the intermediate assignment to a? Essentially I want to avoid having to name the array and just have some allocated array which I have the address for. Is this possible in Fortran? A linked list is possible but I really want the O(1) (?) performance of being able to access any member of the array instead of having to traverse the list, which will be millions of elements long. – Luke May 26 '21 at 17:48
  • I suppose the crux of the issue is being able to allocate a 2d array where the 2nd dimension can vary significantly. The magic word I needed to look for was "Ragged Array" and it seems [this](https://stackoverflow.com/questions/18316592/multidimensional-array-with-different-lengths) post answers my question – Luke May 26 '21 at 17:58