Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

allocatable array produces "INVALID WRITE OF SIZE 4"

Status
Not open for further replies.

emloot

Programmer
Apr 20, 2009
3
DE
Hello!
I still have a problem allocating derived datatypes.
My setup now reads as followed:
I have a module_gv in which my derived datatype is declared like this:

type, public :: w_field
sequence
double precision :: wx,wy,wz
end type w_field

type(w_field),allocatable,dimension:),:,:) :: w

then in the program main main.F90
i declared:

use module_gv
allocate(w(32,32,32))
write(*,*) allocated(w), " w allocated position 1"

w is being used in another subroutine sub(w) which is called in main.F90 after allocation and it has the following declarations with respect to w:

subroutine sub(w)
implicit none
use module_gv
type (w_field),dimension(32,32,32)::w
double precision:: wx,wy,wz
write(*,*) shape(w) , "size of w"
write(*,*) allocated(w) , " that w is allocated" !command #1
w(2,3,4)%wx=3 !command #2
write(*,*) w(2,3,4)%wx , " =3 "

compiling the code with gfortran and command #1 and #2 on gets me the following message:

ERROR 'array' argument of 'allocated' intrinsic at (1) must be allocatable

compiling the code with command #2 on and #1 off reports no compiling errors.but when i actually run the code with valgrind -v it still gives me following message and error:

T w allocated at position 1 !so this worked
invalid write of size 4 ! ERROR
at sub ! w is being used in subroutine sub
...

i think something is wrong with my declarations within sub so that w is not beeing recognised as an allocatable array in sub(which should be already allocated as confirmed in main.F90 )
i would be glad if someone could help me with this error!
thanks alot!
 
Here is what works:

module_gv.f90
Code:
[COLOR=#a020f0]module[/color] module_gv
  [COLOR=#2e8b57][b]type[/b][/color], [COLOR=#2e8b57][b]public[/b][/color] :: w_field 
    [COLOR=#2e8b57][b]sequence[/b][/color]
    [COLOR=#2e8b57][b]double precision[/b][/color] :: wx,wy,wz
  [COLOR=#2e8b57][b]end type[/b][/color] w_field
[COLOR=#a020f0]end module[/color] module_gv

Look how the subroutines are defined:
sub.f90
Code:
[COLOR=#a020f0]subroutine[/color] sub(w)
  [COLOR=#a020f0]use[/color] module_gv

  [COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]none[/b][/color]

  [COLOR=#2e8b57][b]type[/b][/color](w_field),[COLOR=#2e8b57][b]dimension[/b][/color]([COLOR=#ff00ff]32[/color],[COLOR=#ff00ff]32[/color],[COLOR=#ff00ff]32[/color]) :: w

  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]'* calling subroutine SUB'[/color]
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#008080]shape[/color](w) , [COLOR=#ff00ff]"size of w"[/color]
  [COLOR=#0000ff]! when w is not allocatable this doesn't work:[/color]
  [COLOR=#0000ff]!write(*,*) allocated(w) , " that w is allocated" !command #1[/color]
  w([COLOR=#ff00ff]2[/color],[COLOR=#ff00ff]3[/color],[COLOR=#ff00ff]4[/color])%wx[COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]3[/color]                                    [COLOR=#0000ff]!command #2[/color]
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) w([COLOR=#ff00ff]2[/color],[COLOR=#ff00ff]3[/color],[COLOR=#ff00ff]4[/color])%wx , [COLOR=#ff00ff]" =3 "[/color]        
[COLOR=#a020f0]end subroutine[/color] sub

[COLOR=#a020f0]subroutine[/color] sub2(w)
  [COLOR=#a020f0]use[/color] module_gv

  [COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]none[/b][/color]

  [COLOR=#2e8b57][b]type[/b][/color](w_field),[COLOR=#2e8b57][b]allocatable[/b][/color],[COLOR=#2e8b57][b]dimension[/b][/color](:,:,:) :: w

  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]'* calling subroutine SUB2'[/color]  
  [COLOR=#0000ff]! allocating[/color]
  [COLOR=#804040][b]allocate[/b][/color](w([COLOR=#ff00ff]32[/color],[COLOR=#ff00ff]32[/color],[COLOR=#ff00ff]32[/color]))

  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#008080]shape[/color](w) , [COLOR=#ff00ff]"size of w"[/color]
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#008080]allocated[/color](w) , [COLOR=#ff00ff]" that w is allocated"[/color] [COLOR=#0000ff]!command #1[/color]
  w([COLOR=#ff00ff]2[/color],[COLOR=#ff00ff]3[/color],[COLOR=#ff00ff]4[/color])%wx[COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]5[/color]                                    [COLOR=#0000ff]!command #2[/color]
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) w([COLOR=#ff00ff]2[/color],[COLOR=#ff00ff]3[/color],[COLOR=#ff00ff]4[/color])%wx , [COLOR=#ff00ff]" =5 "[/color]      
[COLOR=#a020f0]end subroutine[/color] sub2
As you see, the first subroutine sub works with fixed size parameter w.
Therefore if you uncomment the line with the intrinsic function allocated() and try to compile, you get the error:
Code:
$ gfortran module_gv.f90 sub.f90 main.f90 -o main
[COLOR=red]sub.f90:11.23:

  write(*,*) allocated(w) , " that w is allocated" !command #1
                      1
Error: 'array' argument of 'allocated' intrinsic at (1) must be ALLOCATABLE
[/color]
The second subroutine sub2 works with allocatable parameter w. Here the intrinsic function allocated() works.

main.f90
Code:
[COLOR=#a020f0]program[/color] main
  [COLOR=#a020f0]use[/color] module_gv

  [COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]none[/b][/color]

  [COLOR=#2e8b57][b]type[/b][/color](w_field),[COLOR=#2e8b57][b]allocatable[/b][/color],[COLOR=#2e8b57][b]dimension[/b][/color](:,:,:) :: w

  [COLOR=#804040][b]allocate[/b][/color](w([COLOR=#ff00ff]32[/color],[COLOR=#ff00ff]32[/color],[COLOR=#ff00ff]32[/color]))
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#008080]allocated[/color](w), [COLOR=#ff00ff]" w allocated position 1"[/color]

  [COLOR=#a020f0]call[/color] sub(w)
  [COLOR=#a020f0]call[/color] sub2(w)
  [COLOR=#a020f0]call[/color] sub(w)
[COLOR=#a020f0]end program[/color] main

Compilation:
Code:
$ gfortran module_gv.f90 sub.f90 main.f90 -o main
Output:
Code:
$ main
 T  w allocated position 1
 * calling subroutine SUB
          32          32          32 size of w
   3.0000000000000000       =3 
 * calling subroutine SUB2
          32          32          32 size of w
 T  that w is allocated
   5.0000000000000000       =5 
 * calling subroutine SUB
          32          32          32 size of w
   3.0000000000000000       =3

 
Hello! Thank you for your reply! i implemented the structure you proposed but it leaves me with another error which is connected with the calculation of my field w. w is calculated within sub(u,w) from another field u. it ist also declared within module_gv , also has 3 double precision components .(similar to w)

in module_gv declarations read
type, public:: u_field; sequence
double precision::ux , uy , uz
end type u_field

in sub(u,w) and main.F90 declarations read

use module_gv
type(u_field),dimension(is:ie,js:je,ks:ke)::u
type(w_field),allocatable,dimension:),:,:)::w

the components of u are allocated elsewhere and is,ie,js,je,ks,ke are constants set by the user at the beginning of the simulation.
after i put in the structure you gave me it now returned me the error

array 'u' must have constant shape

I'm not sure why i have this error. the size (shape) of w depends on the size of u but since w is allocatable it should not matter ?! i hope you can give me a hint with this one . i can post more of the code but i'm not sure what else but declarations matters at this point.
thanks a lot
 
Hi emloot,

The compiler says you what si wrong. If I try to compile what you suggested I get
Code:
$ gfortran module_gv.f90 sub.f90 main.f90 -o main
main.f90:6.26:

  type(u_field),dimension(is:ie,js:je,ks:ke) :: u
                         1
Error: Variable 'is' cannot appear in the expression at (1)
main.f90:6.29:

  type(u_field),dimension(is:ie,js:je,ks:ke) :: u
                            1
Error: Variable 'ie' cannot appear in the expression at (1)
main.f90:6.32:

  type(u_field),dimension(is:ie,js:je,ks:ke) :: u
                               1
Error: Variable 'js' cannot appear in the expression at (1)
main.f90:6.35:

  type(u_field),dimension(is:ie,js:je,ks:ke) :: u
                                  1
Error: Variable 'je' cannot appear in the expression at (1)
main.f90:6.38:

  type(u_field),dimension(is:ie,js:je,ks:ke) :: u
                                     1
Error: Variable 'ks' cannot appear in the expression at (1)
main.f90:6.41:

  type(u_field),dimension(is:ie,js:je,ks:ke) :: u
                                        1
Error: Variable 'ke' cannot appear in the expression at (1)
main.f90:6.49:

  type(u_field),dimension(is:ie,js:je,ks:ke) :: u
                                                1
Error: The module or main program array 'u' at (1) must have constant shape
So you see, that the variables is,ie,js,je,ks,ke cannot appear in the expression:
type(u_field),dimension(is:ie,js:je,ks:ke) :: u


If I would instead use the constant shape, for example

type(u_field),dimension(1:5,20:30,100:200) :: u

then the compilation works.

So with in the array declaration you can only use the constant shape or allocatable.

You say taht:
> the components of u are allocated elsewhere and is,ie,js,je,ks,ke are constants set by the user at the beginning of the simulation
But when it is so, then declare the field as an allocatable and then work only with the array portion delimited by the user indices is,ie,js,je,ks,ke.
 
If I would you, I would do the following:
Declare only one type for both fields
module_gv.f90
Code:
[COLOR=#a020f0]module[/color] module_gv
  [COLOR=#2e8b57][b]type[/b][/color], [COLOR=#2e8b57][b]public[/b][/color] :: my_field 
    [COLOR=#2e8b57][b]sequence[/b][/color]
    [COLOR=#2e8b57][b]double precision[/b][/color] :: x,y,z
  [COLOR=#2e8b57][b]end type[/b][/color] my_field
[COLOR=#a020f0]end module[/color] module_gv

In sub.f90 only the field type name changed
Code:
[COLOR=#a020f0]subroutine[/color] sub(w)
  [COLOR=#a020f0]use[/color] module_gv

  [COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]none[/b][/color]

  [COLOR=#2e8b57][b]type[/b][/color](my_field),[COLOR=#2e8b57][b]dimension[/b][/color]([COLOR=#ff00ff]32[/color],[COLOR=#ff00ff]32[/color],[COLOR=#ff00ff]32[/color]) :: w

  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]'* calling subroutine SUB'[/color]
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#008080]shape[/color](w) , [COLOR=#ff00ff]"size of w"[/color]
  [COLOR=#0000ff]! when w is not allocatable this doesn't work:[/color]
  [COLOR=#0000ff]!write(*,*) allocated(w) , " that w is allocated" !command #1[/color]
  w([COLOR=#ff00ff]2[/color],[COLOR=#ff00ff]3[/color],[COLOR=#ff00ff]4[/color])%x[COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]3[/color]                                    [COLOR=#0000ff]!command #2[/color]
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) w([COLOR=#ff00ff]2[/color],[COLOR=#ff00ff]3[/color],[COLOR=#ff00ff]4[/color])%x , [COLOR=#ff00ff]" =3 "[/color]        
[COLOR=#a020f0]end subroutine[/color] sub

[COLOR=#a020f0]subroutine[/color] sub2(w)
  [COLOR=#a020f0]use[/color] module_gv

  [COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]none[/b][/color]

  [COLOR=#2e8b57][b]type[/b][/color](my_field),[COLOR=#2e8b57][b]allocatable[/b][/color],[COLOR=#2e8b57][b]dimension[/b][/color](:,:,:) :: w

  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]'* calling subroutine SUB2'[/color]  
  [COLOR=#0000ff]! allocating[/color]
  [COLOR=#804040][b]allocate[/b][/color](w([COLOR=#ff00ff]32[/color],[COLOR=#ff00ff]32[/color],[COLOR=#ff00ff]32[/color]))

  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#008080]shape[/color](w) , [COLOR=#ff00ff]"size of w"[/color]
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#008080]allocated[/color](w) , [COLOR=#ff00ff]" that w is allocated"[/color] [COLOR=#0000ff]!command #1[/color]
  w([COLOR=#ff00ff]2[/color],[COLOR=#ff00ff]3[/color],[COLOR=#ff00ff]4[/color])%x[COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]5[/color]                                    [COLOR=#0000ff]!command #2[/color]
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) w([COLOR=#ff00ff]2[/color],[COLOR=#ff00ff]3[/color],[COLOR=#ff00ff]4[/color])%x , [COLOR=#ff00ff]" =5 "[/color]      
[COLOR=#a020f0]end subroutine[/color] sub2

Here is the
main.f90
Code:
[COLOR=#a020f0]program[/color] main
  [COLOR=#a020f0]use[/color] module_gv

  [COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]none[/b][/color]
  [COLOR=#2e8b57][b]integer[/b][/color] is,ie,js,je,ks,ke, i, j, k
  [COLOR=#2e8b57][b]type[/b][/color](my_field),[COLOR=#2e8b57][b]allocatable[/b][/color],[COLOR=#2e8b57][b]dimension[/b][/color](:,:,:) :: u, w

  [COLOR=#804040][b]allocate[/b][/color](w([COLOR=#ff00ff]32[/color],[COLOR=#ff00ff]32[/color],[COLOR=#ff00ff]32[/color]))
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#008080]allocated[/color](w), [COLOR=#ff00ff]" w allocated position 1"[/color]

  [COLOR=#a020f0]call[/color] sub(w)
  [COLOR=#a020f0]call[/color] sub2(w)
  [COLOR=#a020f0]call[/color] sub(w)

  [COLOR=#0000ff]! user inputs the value of indices is,ie,js,je,ks,ke[/color]
  is[COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]1[/color]
  ie[COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]2[/color]
  js[COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]3[/color]
  je[COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]4[/color]
  ks[COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]5[/color]
  ke[COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]6[/color]
  [COLOR=#0000ff]! then you allocate the shape[/color]
  [COLOR=#804040][b]allocate[/b][/color](u(is:ie,js:je,ks:ke))
  [COLOR=#0000ff]! assign values to the field[/color]
  [COLOR=#804040][b]do[/b][/color] i[COLOR=#804040][b]=[/b][/color]is,ie
    [COLOR=#804040][b]do[/b][/color] j[COLOR=#804040][b]=[/b][/color]js,je
      [COLOR=#804040][b]do[/b][/color] k[COLOR=#804040][b]=[/b][/color]ks,ke
        u(i,j,k)%x [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]100[/color][COLOR=#804040][b]*[/b][/color]i
        u(i,j,k)%y [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]10[/color][COLOR=#804040][b]*[/b][/color]j
        u(i,j,k)%z [COLOR=#804040][b]=[/b][/color] k
      [COLOR=#804040][b]end do[/b][/color]
    [COLOR=#804040][b]end do[/b][/color]
  [COLOR=#804040][b]end do[/b][/color]
  [COLOR=#0000ff]! print values[/color]
  [COLOR=#804040][b]do[/b][/color] i[COLOR=#804040][b]=[/b][/color]is,ie
    [COLOR=#804040][b]do[/b][/color] j[COLOR=#804040][b]=[/b][/color]js,je
      [COLOR=#804040][b]do[/b][/color] k[COLOR=#804040][b]=[/b][/color]ks,ke
        [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]'u('[/color],i,[COLOR=#ff00ff]','[/color],j,[COLOR=#ff00ff]','[/color],k,[COLOR=#ff00ff]')='[/color],[highlight #ffff00][COLOR=#0000ff]&[/color][/highlight]
        [COLOR=#ff00ff]'['[/color],u(i,j,k)%x,[COLOR=#ff00ff]','[/color],u(i,j,k)%y,[COLOR=#ff00ff]','[/color],u(i,j,k)%z,[COLOR=#ff00ff]']'[/color]
      [COLOR=#804040][b]end do[/b][/color]
    [COLOR=#804040][b]end do[/b][/color]
  [COLOR=#804040][b]end do[/b][/color]  
[COLOR=#a020f0]end program[/color] main

Compilation and output
Code:
$ g95 module_gv.f90 sub.f90 main.f90 -o main

$ main
 T  w allocated position 1
 * calling subroutine SUB
 32 32 32 size of w
 3.  =3 
 * calling subroutine SUB2
 32 32 32 size of w
 T  that w is allocated
 5.  =5 
 * calling subroutine SUB
 32 32 32 size of w
 3.  =3 
 u( 1 , 3 , 5 )=[ 100. , 30. , 5. ]
 u( 1 , 3 , 6 )=[ 100. , 30. , 6. ]
 u( 1 , 4 , 5 )=[ 100. , 40. , 5. ]
 u( 1 , 4 , 6 )=[ 100. , 40. , 6. ]
 u( 2 , 3 , 5 )=[ 200. , 30. , 5. ]
 u( 2 , 3 , 6 )=[ 200. , 30. , 6. ]
 u( 2 , 4 , 5 )=[ 200. , 40. , 5. ]
 u( 2 , 4 , 6 )=[ 200. , 40. , 6. ]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top