0

I want to be able to reset elements in an array which are not in a consecutive block of memory. I thought to use an array of pointers for this rather than a pointer array, as my understanding of pointer arrays is that they must point to a coherent block of memory (e.g pointer(1:10,1:10) => target(1:100) )

My simple test program is as follows:

program test
  implicit none

  integer, target :: arr(4,4)

  type ptr
    integer, pointer :: p
  end type ptr

  type(ptr), dimension(2) :: idx 

  arr=0

  idx(1)%p=>arr(2,2) 
  idx(2)%p=>arr(4,2)

  idx(1)%p=5 ! this is okay 
  idx(2)%p=5 ! this is okay  
  idx(1:2)%p=5 ! this gives an error

  print *,arr

end program test

The first two statements idx(n)%p=5 are okay, but I want to be able to set a chunk of the array in one statement using the spanning method idx(1:n)%p=5 but when I do this I get the following compile error:

Error: Component to the right of a part reference with nonzero rank must not have the POINTER attribute at (1)

Can I set the value of a chunk of array entries using pointer somehow? Perhaps it is in fact possible with a pointer array rather than an array of pointers...

I think this is related to Fortran: using a vector to index a multidimensional array

but I can't see how to use that answer here.

1 Answer 1

1

Probably an extended comment rather than an answer, but I need a little formatting ...

It's best not to think of Fortran supporting arrays of pointers. You've already grasped that (I think) and built the usual workaround of an array of derived type each instance of the type having an element which is a pointer.

What's not entirely clear is why you don't use multiple vector subscripts such as

arr([2,4],[2]) = 5

(OK, the second subscript is something of a degenerate vector but the statement is intended to have the same effect as your attempt to use pointers.) If you would rather, you could use array subscript triplets instead

arr(2:4:2,2) = 5

Perhaps you've simplified your needs too far to express the necessity of using pointers in which case my feeble suggestions will not meet your undeclared needs.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the notes Mark :) In fact I have gone back and coded up a solution for the moment that does exactly that, using an index array to index the data array. It is just that, as pointed out (no pun intended) in the other stackoverflow question I link to, I seem to have to pick out each coordinate in turn (using index 1,2,3 manually) : imark(memf3d(1:memf3dp,1),memf3d(1:memf3dp,2),memf3d(1:memf3dp,3))=1 I don't like hardcoding in this way as thought that pointers might provide a more flexible solution, but it seems that this may not be possible from what you say. Thanks!
Your comment makes me wonder if you are asking what has become known hereabouts as an X/Y question -- see for example meta.stackoverflow.com/questions/333921/…. I wonder if your question shouldn't be How can I make assignments to (or operate on) non-contiguous array sections ?. If that is your real question, ask it.
I'm not really sure it is an X/Y question, I don't really understand why I can't use the same notation idx(:)%p as you can for a normal array. But in the end I went back to using pointers in a loop, as the solution in my edit above didn't do as I intended (of course!) since arr([2,4],[3,2]) sets 4 elements not 2, so even using the direct indexing I needed to loop through the coordinate vector. Therefore if a loop is required, do i=1,n idx(i)%p=5 end do is neater (and uses less memory?). That is a long way of saying, my question really is how to use pointers (without looping) to address arr

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.