Smart questions
Smart answers
Smart people
INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Member Login




Remember Me
Forgot Password?
Join Us!

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips now!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

Join Tek-Tips
*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Donate Today!

Do you enjoy these
technical forums?
Donate Today! Click Here

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.
Jobs from Indeed

Link To This Forum!

Partner Button
Add Stickiness To Your Site By Linking To This Professionally Managed Technical Forum.
Just copy and paste the
code below into your site.

derived data type with allocatable elementHelpful Member! 

albi73 (Programmer)
16 Sep 10 11:18
please help me to understand this point before I will waste time.

I'd like to understand if it is possible to use allocatable into a "type structure". I tested this easy code:

program test_allocation
      type elettrone
              real,allocatable, dimension (:,:) :: vx
              !real,pointer, dimension (:,:) :: vx
      end type

      type(elettrone) :: mpi
      allocate(mpi%vx(1:2,1:3))
      mpi%vx=reshape((/1,2,3,4,5,6/),(/2,3/))


      print *,mpi%vx
      !print *,mpi
      read (*,*)
end program

It well works, but if i use the line "print *,mpi" (above commented), I obtain the following error message: .... a derived type ultimately contains an allocatable component cannot be specified in the i/o item.

My question is:
may I use allocatable array in to a "type structure"? Why  above - in same cases - it seems to work but on books I read that it is not permitted and that one must use pointers? (again above using the pointer the result is the same)
Can I go ahead using the allocatable array as i did before thinking to use a more structurated programming?

I hope you'll halp me to figure out this point.

Thanks, Albi73
Helpful Member!  FJacq (Programmer)
16 Sep 10 12:45
The use of allocatable arrays has been made much more flexible in F2003 than in F95. In particular, they are authorized as dummy arguments or within derived types.

Fortunately, as this extension was the subject of a rather old technical recommendation, most of f95 compilers implement it (I call that F95+).

Do not hesitate to use, if possible, allocatable in place of pointer ! The memory management is much safer with allocatable than pointer (no risk of memory leak).

I always try to limit the use of pointers to their basic function :  pointing to (more exactly aliasing) a memory area already allocated.

About print or write statements concerning whole derived type variables, they are limited to the ones without allocatable or pointer elements. Why ? I don't remember. I just remember having seen an explanation in the past but I forgot it.

So, if you replace ALLOCATABLE by POINTER, you will get a similar error message.
albi73 (Programmer)
17 Sep 10 10:19
Thanks a lot dear FJacq, but clearly -just starting to construct my structure - I stopped on a point that makes me mad.
I hope you will give a look to these few lines:
program test_allocation
      type elettrone
              real,pointer, dimension (:) :: gene
              integer :: id
      end type

      type(elettrone),dimension(1:3) :: mpi
      allocate(mpi%gene(1:2))
      !allocate(mpi(1)%gene(1:2))
      !allocate(mpi(2)%gene(1:2))
      mpi(1)%gene=(/1,2/)
      mpi(2)%gene=(/1,4/)
      mpi(1)%id=10

      print *,mpi(1)%gene(:)
      print *,mpi(2)%gene(:)
      !print *,mpi(1)%id
      read (*,*)
end program

error: Component mpi to right of part references with nonzero rank must not have pointer attribute

changing the three lines:
      !allocate(mpi%gene(1:2))
      allocate(mpi(1)%gene(1:2))
      allocate(mpi(2)%gene(1:2))
it works!

I can't believe that to overcome this point one needs to write a loop something like:
do i= ...
      allocate(mpi(i)%gene(1:2))
end do
I'd like to think that there is a much smart way to allocate this array derived type

Ciao, Albi73
 
FJacq (Programmer)
17 Sep 10 13:16
Sorry but you need the loop !

The limitation is much deeper than you could think. FORTRAN makes invalid any reference to an array of array.

The reason is in fact simple : the distance between two successive elements of an array among each dimension must be constant. This is necessary to keep in the same time high performances and a pointer enough simple (a pointer contains that distance over each dimension).

With an array of array, this cannot be warranted.

Even after the allocation, you cannot set all the arrays with a single instruction :

CODE

      allocate(mpi(1)%gene(1:2))
      allocate(mpi(2)%gene(1:2))
      mpi%gene=0 ! => error

The error does not come from the POINTER attribute but from the reason I have indicated. Change POINTER into ALLOCATABLE and you will get the same trouble.

Even if the array GENE has a constant size, you cannot use mpi%gene. In theory, this is the only case which could be acceptable but there are many corner cases which make it too dangerous. So the rule is strict : no array of array !

CODE

PROGRAM tt
  TYPE t
    INTEGER :: tab(10)
  END TYPE
  TYPE(t) :: o(3)
  o%tab=0
  write(*,*) o%tab
END PROGRAM

tt.f90(6): error #6159: A component cannot be an array if the encompassing structure is an array.       

Now, look at the following programming which is OK :

CODE

 PROGRAM test
  TYPE t
    INTEGER :: tab(:)
  END TYPE
  TYPE(t) :: o(3)
  DO i=1,3
    o(i)%tab=i
  ENDDO
  write(*,*) o%tab(4)
END PROGRAM

Indeed, o%tab(4) is a vector of 3 values, all successive elements being the same distance.

For the same reason, the next example is forbidden again :

CODE

PROGRAM test
  TYPE t
    INTEGER,ALLOCATABLE :: tab(:)
  END TYPE
  TYPE(t) :: o(3)
  DO i=1,3
    ALLOCATE(o(i)%tab(10))
    o(i)%tab=i
  ENDDO
  write(*,*) o%tab(4)
END PROGRAM

Error message :
tt.f90(10): error #7828: The part-name to the right of a part-ref with nonzero rank has the ALLOCATABLE attribute (6.1.2).       

Changing ALLOCATABLE into POINTER does not change the result : the compiler cannot warrant a constant distance between two successive elements in the "vector" o%tab(4).

 
albi73 (Programmer)
20 Sep 10 5:36
Ok so if I find a trick to load an array of arrays - loading the components one by one (like with a loop) -  it works; what is important into the code -if i have well understood- is that one must never write the espresion of array of arrays ... this has sense.
I suppose in your test program :

PROGRAM test
  TYPE t
    INTEGER :: tab(:)
  END TYPE
  TYPE(t) :: o(3)
  DO i=1,3
    o(i)%tab=i
  ENDDO
  write(*,*) o%tab(4)
END PROGRAM  

The third line have to be:     INTEGER :: tab(10)
;with dimension specified.

Your suggestions are always very precious.
Thanks, Albi

FJacq (Programmer)
20 Sep 10 5:59
Right ! Sorry for the typo ...

As you have surely noticed, the last example did not concern array of array but the restriction about array expressions in a more general manner : even a "vector" expression may be invalid if the compiler cannot insure a constant stride.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members!

Back To Forum

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close