- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear all,
Could I ask a question regarding resizing an allocatable array? Thank you very much for all your help!
Here is an example:
========================================================
[bash] Module mod1 type a integer, allocatable :: a1(:) end type a type(a), allocatable :: b(:) End Module mod1 Program main Use mod1 type(a) b1, b2 allocate(b1%a1(2)) allocate(b2%a1(2)) do i = 1, 2 b1%a1(i) = i b2%a1(i) = i + 20 end do b = (/ b1 /) write(*,*) 'SIZE(b) = ', SIZE(b) write(*,*) 'b(1)%a1 = ', b(1)%a1 b = (/ b, b2 /) write(*,*) 'SIZE(b) = ', SIZE(b) write(*,*) 'b(1)%a1 = ', b(1)%a1 write(*,*) 'b(2)%a1 = ', b(2)%a1 End [/bash]
========================================================
I compile it with ifort 11.1:
ifort -g -assume realloc_lhs resize_array.f90
Here is the result:
========================================================
SIZE(b) = 1
b(1)%a1 = 1 2
SIZE(b) = 2
b(1)%a1 = 0 0
b(2)%a1 = 21 22
========================================================
b(1)%a1 should still be "1 2". I am not sure what I did wrong. Thanks a lot for your attention.
Best regards,
Victor
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Steve,
Thank you very much for your so quick response!
We have a major project now to restructure a very old Fortran program. We need to be able to resize an allocatable array such that we can insert/remove an entry to/from an array. I am wondering do you have any suggestions for a workaround at this time?
Thank you again very much for your help!
Best regards,
Victor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
[fortran] Module mod1 type a integer, allocatable :: a1(:) end type a type(a), allocatable :: b(:) End Module mod1 Program main Use mod1 type(a) b1, b2 type(a), allocatable :: btmp(:) allocate(b1%a1(2)) allocate(b2%a1(2)) do i = 1, 2 b1%a1(i) = i b2%a1(i) = i + 20 end do b = (/ b1 /) write(*,*) 'SIZE(b) = ', SIZE(b) write(*,*) 'b(1)%a1 = ', b(1)%a1 btmp = (/ b, b2 /) call move_alloc (btmp, b) write(*,*) 'SIZE(b) = ', SIZE(b) write(*,*) 'b(1)%a1 = ', b(1)%a1 write(*,*) 'b(2)%a1 = ', b(2)%a1 End [/fortran]After the move_alloc, btmp is deallocated and the old storage associated with b is also deallocated. I'm not sure how you're removing items, but the same principle could be used assuming you're referencing a slice of b in the array constructor.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Steve,
Thank you so much for your kind help! This will help us a lot!
I am using the following statement to remove the m-th element from a SIZE-n array a:
atmp = (/(a(j),j=1,m-1), (a(j),j=m+1,n)/)
call move_alloc (atmp, a)
Thanks again very much!
Best regards,
Victor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Best regards,
Victor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
1. The readability of
atmp = (/(a(j),j=1,m-1), (a(j),j=m+1,n)/)
might be improved by writing it as
atmp = [a(1:m-1),a(m+1:n)]
2. On the other hand, the nominal semantics of this statement is to first create the constructor value, and then allocate atmp and copy the values from the constructor to atmp. If the generated code actually does that, each value is first copied to the compiler temp holding the constructor value and then copied a second time to atmp. Optimizing compilers should be clever enough to avoid this double copying, but I don't like to depend on compilers being clever, so I would choose to explicitly copy values directly from a to atmp:
allocate(atmp(n-1))
atmp(1:m-1)=a(1:m_1)
atmp(m:n-1)=a(m+1:n)
Because the allocate is explicit here, this does not require "-assume realloc_lhs", and it will work in some cases where the standard does not provide for automatic allocation (e.g., when intrinsic assignment has been overridden by a user-defined assignment procedure). I suspect it is also more readable in cases where you are doing reallocation of an array with more than one dimension (because the constructors for multi-dimensional arrays tend to be very messy).
3. Finally, I would choose to write the call to MOVE_ALLOC using keyword argument association:
call move_alloc(from=atmp, to=a)
Even though I am the person who actually proposed MOVE_ALLOC to J3 during the development of F2003, I can never remember (without looking at the documentation) whether the source array or the destination array comes first in the argument list. I suspect others might have the same problem. Rather than making them consult the documentation when trying to understand this statement, I would would use the keywords to make the statement self-documenting on this point.
With the Intel compiler, it is quite likely that none of the above suggestions have any noticeable effect on the speed of compilation or the speed of the running code, so these are really just a matter of style. You will have to decide for yourself whether any of these are an improvement in things like the readability of your code, the maintainability of your code, or the ease with which your code can be transported to a new platform.
-Kurt
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Kurt,
Thank you very much for your valuable suggestions!
I totally agree with your points 1 and 3. For your point 2, using atmp is only a temporary solution (until the bug is fixed) and it will be eventually replaced by
a = [a(1:m-1),a(m+1:n)]
Thanks again for your help!
Best regards,
Victor

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page