INTELLIGENT WORK FORUMS FOR COMPUTER PROFESSIONALS
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!
*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.
Partner With Us!
"Best Of Breed" Forums Add Stickiness To Your Site

(Download This Button Today!)
Feedback
"...These forums are an excellent source and example of the way people can help each other..."
Geography
Where in the world do Tek-Tips members come from?
|
derived data type with allocatable element
|
|
|
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 |
|
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 ! CODEPROGRAM 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 : CODEPROGRAM 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. |
|
|
 |
|