I wish to create jagged arrays in Fortran with multiple levels of allocation. However I run in to the error of "There is no specific subroutine for the generic ‘new’ at (1)" for both my constructor and destructor procedures.
I'm quite new at Fortran. I believe the problem is my 1st argument "M1" doesn't fit. However, I can't seem to figure out why.
module JaggedArrayModule
implicit none
save
private
public JaggedArray, New, Delete
type JaggedArray
private
real, allocatable :: vector(:)
end type
interface New
module procedure NewMatrix
end interface
interface Delete
module procedure DeleteMatrix
end interface
contains
subroutine NewMatrix(Matrix, maxsize)
type (JaggedArray), intent(out), allocatable :: Matrix(:)
integer :: maxsize, i
allocate(Matrix(maxsize))
do i=1, maxsize
allocate(Matrix(i)%vector(i))
enddo
end subroutine
subroutine DeleteMatrix(Matrix, maxsize)
type (JaggedArray), intent(inout), allocatable :: Matrix(:)
integer :: maxsize, i
do i=1, maxsize
deallocate(Matrix(i)%vector(i))
enddo
deallocate(Matrix)
end subroutine
end module
program main
use JaggedArrayModule
type (JaggedArray) :: M1(5)
call New(M1, 10)
call Delete(M1, 10)
end program
In these case the best way to debug the error message is to call the actual specific subroutine. That means to call NewMatrix
instead of Matrix
.
Then you will get
call NewMatrix(M1, 10)
1
Error: Actual argument for ‘matrix’ must be ALLOCATABLE at (1)
jagged.f90:51:18:
call DeleteMatrix(M1, 10)
1
Error: Actual argument for ‘matrix’ must be ALLOCATABLE at (1)
That is pretty much self-explanatory. M1
must be allocatable
to be passed to a subroutine that has an allocatable dummy argument. In modern Fortran generic disambiguation also considers the allocatable attribute. That is why you get the original error message.
Be aware that I get also this error for your code:
jagged.f90:37:17:
deallocate(Matrix(i)%vector(i))
1
Error: Allocate-object at (1) must be ALLOCATABLE or a POINTER
You should use just
deallocate(Matrix(i)%vector)
However, the allocatable components are deallocated automatically. There is no need for a specialized (finalization) subroutine that does that.
The allocate statement
allocate(Matrix(i)%vector(i))
also probably wants some other size, and not i
, but only you know that.