Re-size array within a subroutine

Re-size array within a subroutine

I am trying to implement a push_back routine as below. 

SUBROUTINE push_back(array, val)
    INTEGER,DIMENSION(:), ALLOCATABLE :: tmp_arr
    INTEGER, DIMENSION(:) :: array
    INTEGER val
    ALLOCATE(tmp_arr(0 : SIZE(array)))
    tmp_arr(0:(SIZE(array)-1))=array
    tmp_arr(SIZE(array)) = val
    DEALLOCATE(array)
    ALLOCATE(array(0:SIZE(tmp_arr)-1))
    CALL move_alloc(tmp_arr, array)
END SUBROUTINE push_back 

On resizing an allocatable array (declared ALLOCATABLE in the calling subroutine) , I get the following compile errors

  • error #6724: An allocate/deallocate object must have the ALLOCATABLE or POINTER attribute. [ARRAY]
  • error #8195: The argument to the MOVE_ALLOC intrinsic subroutine shall be an allocatable object. [MOVE_ALLOC]

I want the resize to work such that the data that is passed is not lost. However, by making array ALLOCATABLE within the subroutine , I would lose the existing data.
Any help with this would be great. 

publicaciones de 8 / 0 nuevos
Último envío
Para obtener más información sobre las optimizaciones del compilador, consulte el aviso sobre la optimización.

INTEGER, DIMENSION(:), ALLOCATABLE :: array

you forgot to tell the compiler that "array" was also allocatable.
Les

Is this something that you want to reach?

SUBROUTINE UTIL_ADDTO_ARRAYint2Allocarray(ToBeAdded,IntegerArray) !{
! This subroutine adds a single value to the end of an integer array.
IMPLICIT NONE
!** HEADER VARIABLES/ARGUMENTS
INTEGER, INTENT(IN) ::ToBeAdded
INTEGER, ALLOCATABLE ::IntegerArray(:)
!*****************************************************************************
!** LOCAL VARIABLES
INTEGER ::NewSize
INTEGER ::OldSize
INTEGER, ALLOCATABLE ::CopyArray(:)
!*************************************************************************

IF (allocated(IntegerArray)) THEN
OldSize=size(IntegerArray)
NewSize = OldSize + 1
ALLOCATE(CopyArray(NewSize))
CALL MOVE_ALLOC(CopyArray, IntegerArray)
IntegerArray(NewSize) = ToBeAdded
ELSE
ALLOCATE(IntegerArray(1))
IntegerArray(1)=ToBeAdded
ENDIF

ENDSUBROUTINE UTIL_ADDTO_ARRAYint2Allocarray !}

Making the array allocatable within the subroutine does not lose your data.

regards,
Dirk

On making array 'ALLOCATABLE ' with

INTEGER, DIMENSION(:), ALLOCATABLE :: array

I would lose its existing allocation and its data and I would like to retain that.

Best Reply

Merely declaring an argument array to be ALLOCATABLE does not change its allocation status or contents.

The following program works fine


program tpush

IMPLICIT NONE

INTEGER, DIMENSION(:), ALLOCATABLE :: ivec

INTEGER :: val=4

ALLOCATE(ivec(3))

ivec=(/1,2,3/)

call push_back(ivec, val)

write(*,'(10I4)')ivec
contains

SUBROUTINE push_back(array, val)

    INTEGER,DIMENSION(:), ALLOCATABLE :: tmp_arr

    INTEGER, DIMENSION(:),ALLOCATABLE :: array

    INTEGER val

    ALLOCATE(tmp_arr(0 : SIZE(array)))

    tmp_arr(0:(SIZE(array)-1))=array

    tmp_arr(SIZE(array)) = val

    DEALLOCATE(array)

    ALLOCATE(array(0:SIZE(tmp_arr)-1))

    CALL move_alloc(tmp_arr, array)

END SUBROUTINE push_back

END PROGRAM tpush

The program prints out

   1   2   3   4

[Complaints re ISDN forum software: (i) The program source code above appears single-spaced in edit mode, but appears mostly double spaced in browse mode; (ii) It is confusing when the OP replies to other people's responses and there are no response numbers to provide information on which response is being replied to .]

Sorry, It was my bad.

I had overlooked the allocation of the array with a zero index in the calling function . It works now.
@Les & @Dirk - Thank you very much for the inputs.

Sangeetha

It was totally my bad. Thank you very much, mecej4.

That's ok - we all make mistakes. Glad it now works
Les

Inicie sesión para dejar un comentario.