Home > Software design >  How to initialize the size of an array in fortran module
How to initialize the size of an array in fortran module

Time:05-29

I'm trying to create my own module of array (just for practicing). I wrote this module.

module myArray
    implicit none

    public set, get

    integer :: size = 5
    integer, allocatable :: array(:)
    allocate(array(size))
    
    contains

    subroutine set(index, value)
        implicit none
        integer, intent(in) :: index
        integer, intent(in) :: value
        array(index) = value
    end subroutine set
    
    function get(index) result(value)
        implicit none
        integer, intent(in) :: index
        integer :: value
        value = array(index)
    end function get

end module myArray

But I get this error

mymod.f90:8:25:

    8 |     allocate(array(size))
      |                         1
Error: Unexpected ALLOCATE statement in MODULE at (1)

What should I do to correct this?

CodePudding user response:

You cannot put executable statements directly into a module. You have to create a subroutine, put the statements into the subroutine and then call the subroutine in some way.

CodePudding user response:

The idea is right but you're placing global data in a module, it won't be usable in the real world. You want to define a class for your array type. In fortran, you define a derived type binding both data and methods:

module myArrays
   implicit none

   type, public :: myArray
      
      ! Data here
      integer :: n = 0
      integer, allocatable :: array(:)
      
      contains
         ! Type-bound procedures here
         procedure :: set
         procedure :: get
         procedure :: new
   end type myArray 

contains

   elemental subroutine set(this,index,value)
      class(myArray), intent(inout) :: this
      integer, intent(in) :: index,value
      if (index>0 .and. index<=this%n) this%array(index) = value
   end subroutine set

   elemental integer function get(this, index) result(value)
      class(myArray), intent(in) :: this
      integer, intent(in) :: index
      if (index>0 .and. index<=this%n) then 
         value = this%array(index)
      else
         value = -huge(value) ! return an "invalid" value
      endif
   end function get

   elemental subroutine new(this, size)
      class(myArray), intent(inout) :: this
      integer, intent(in) :: size
      integer :: ierr

      ! This should go in a destructor routine
      this%n=0 
      deallocate(this%array,stat=ierr)

      ! Now allocate
      if (size>0) then 
         this%n=size
         allocate(this%array(Size),stat=ierr) 
      endif
   end subroutine new


end module myArrays

Note that you'll have to call the initializer routine new before using your array. Here's a program example:

program test_myArray
   use myArrays
   implicit none

   type(myArray) :: A,B

   call A%new(size=10)
   call B%new(size=20)

   print *, 'A size=',A%n,' B size=',B%n

end program
  • Related