Fortran increase dynamic array size in function

前端 未结 3 1041
滥情空心
滥情空心 2020-12-30 13:28

I need a variable size array in Fortran. In C++ I would use vector. So I have a function like

integer function append(n, array, value)
  integer, pointer, d         


        
相关标签:
3条回答
  • 2020-12-30 13:53

    The answer by IRO-bot is the correct approach for Fortran 90. If you can limit yourself to compilers that support the Fortran 2003 MOVE_ALLOC intrinsic (included in gfortran since the 4.2 release), you can avoid one of the copies. That is, increasing the size of an array by a factor of 2 can be written as

    
    allocate(tmp_arr(2*size(array)))
    tmp_arr(1:size(array)) = array
    deallocate(array)
    move_alloc(tmp_arr, array)
    ! tmp_arr is now deallocated
    
    0 讨论(0)
  • 2020-12-30 13:59

    Thank you a lot janneb.It was very helpful your comment.

    Only a few change I have made was to omit the deallocate(array) . There was'nt any erro omitting this line in my code. This change is specially helpful if you need to put it into a loop and you don't allocated array before the loop. My specific case follows below (look that I don't allocate x_all before or into the loop):

    begin program test 
      integer,allocatable::x_all(:),tmp_arr(:)
      integer,allocatable::x_tmp(:)
      integer::N
      allocate(x_tmp(2*N))
      (...)
    
      i=1
      do while(logical test)
        ...
        x_tmp(i)=some calculus
        i=i+1
        ...
      end do
      i=i-1
      allocate( tmp_arr( 1:(i+size(x_all) ) ) )
      tmp_arr(1:size(x_all))=x_all
      tmp_arr(size(x_all)+1:)=xtemp
      call MOVE_ALLOC(tmp_arr,x_all)  
      ...
    end program
    
    0 讨论(0)
  • 2020-12-30 14:03

    OK, the problem is that you cannot deallocate and re-allocate the array that you are assigning a function value to. You are correct about the cause of your problem (arguments passed by reference and not by value as it is in C). Since you deallocate the array inside the function body, the assignment to that array becomes invalid, leading to segfault. This is not a gfortran issue, tried it with ifort and pgf90, all of them report the same problem. This works for me:

    PROGRAM dynamic_size
    INTEGER,DIMENSION(:),ALLOCATABLE :: array
    
    ALLOCATE(array(10))
    
    array=(/1,2,5,7,4,3,6,5,6,7/)
    
    WRITE(*,*)SIZE(array)
    CALL resize_array
    WRITE(*,*)size(array)
    
    CONTAINS
    
    SUBROUTINE resize_array
    INTEGER,DIMENSION(:),ALLOCATABLE :: tmp_arr
    
    ALLOCATE(tmp_arr(2*SIZE(array)))
    tmp_arr(1:SIZE(array))=array
    DEALLOCATE(array)
    ALLOCATE(array(size(tmp_arr)))
    array=tmp_arr
    
    ENDSUBROUTINE resize_array
    
    ENDPROGRAM dynamic_size
    
    0 讨论(0)
提交回复
热议问题