FORTRAN-Passing array to subroutine-segmentation fault

  • Fortran
  • Thread starter shitij
  • Start date
  • Tags
    Array Fault
In summary, the conversation is about a user who is new to Fortran and is having trouble with a code that passes an array to a subroutine and prints it. There is a discussion about why the size of the array is not being printed correctly in the subroutine and why there is a segmentation fault. The user shares their code and asks for help in understanding the issue. The conversation ends with a solution being shared and the user thanking everyone for their prompt replies and assistance.
  • #1
shitij
19
0
Hi all !

I am new to fortran. Please see the following code. It is a simple code to pass an array to a subroutine and print it, but doesn't behave that way:

Code:
    program exp_realloc
    implicit none

    integer,allocatable,dimension(:,:):: array
    integer::i,j

    allocate(array(3,3))

    write(*,*)size(array,1)," ",size(array,2)

    do i=1,3
        do j=1,3
            array(i,j)=i*j
            write(*,*)array(i,j)
        enddo
        write(*,*)
    enddo

    CALL func(array)

    end program exp_realloc


    subroutine func(array)

    integer,dimension(:,:),intent(in)::array
    integer::i,j

    write(*,*)"********* Inside subroutine **********"
    write(*,*)size(array,1)," ",size(array,2)

    write(*,*)array(1,1)
    write(*,*)array(1,2)
    write(*,*)array(2,1)
    do i=1,3
        do j=1,3
            write(*,*)array(i,j)
        enddo
    enddo

    end subroutine func

The output is:
Code:
    3 3
    1
    2
    3
    2
    4
    6
    3
    6
    9
    ********* Inside subroutine **********
    131097 1
    Segmentation fault

Two questions:

1. Why is the size of array not being printed correctly in the subroutine?
2. Why the segmentation fault? Even array(1,1) can't be accessed?

Thank you in advance !
 
Technology news on Phys.org
  • #2
I'm going to play with this for a minute. Just letting you know someone is looking and doing something.

Alright, done playing. I split your program up into 2 pieces (just preference). I changed the way you allocate your array by defining a parameter named dim (=3) as you can see at the top of main. That way, you don't have these "magic numbers" all around and can easily change loops if you want. When you pass your array to the subroutine, you need to also pass it's dimension (someone correct me if that isn't exactly right; it works). Define the array's dimension and self as an integer with those dimensions. Reformatted a bit. Compiled with

Code:
gfortran garbageij_main.f90 garbageij_sub.f90
./a.exe

Let me know if you need anything else.

Cheers.

Code:
      program garbageij_main
      implicit none

      integer :: i
      integer :: j
      integer, parameter :: dim = 3
      integer, dimension(dim,dim) :: array

      write(*,*) size(array,1), " ", size(array,2)

      do 10 i = 1,dim

         do 20 j = 1,dim

            array(i,j) = i*j
            write(*,*) array(i,j)

 20      continue         

         write(*,*)

 10   continue

      call garbageij_sub(array,dim)

      stop
      return

      end program garbageij_main

Code:
      subroutine garbageij_sub(array,dim)

      integer :: i
      integer :: j
      integer :: dim
      integer, dimension(dim,dim) :: array

      write(*,*) "********* Inside subroutine **********"
      write(*,*) size(array,1), " ", size(array,2)

      write(*,*) array(1,1)
      write(*,*) array(1,2)
      write(*,*) array(2,1)

      do i = 1,dim
         do j = 1,dim
            write(*,*) array(i,j)
         enddo
      enddo

      end subroutine garbageij_sub
 
Last edited:
  • #3
Swartizm''s work-round works, but if you really want to write the routine as
Code:
subroutine func(array)
    integer,dimension(:,:),intent(in)::array
... 
end
you have to do one of two things.

Either write an interface defintion for the subroutine, so the compiler "knows" you are doing this when it complies the CALL FUNC statement.

Or, make the subroutine part of a module, and you then get the interface definition. generated for free.

If you don't do that, the subroutine will get "random" information about the size of the array. That's why the dimensions you printed in the subroutine were wrong, and when it tried to access the elements of the array using those wrong dimensions, the program crashed trying to access part of the computer's memory that didn't belong to your program.

See "Danger of calling Fortran 90 style routines" in http://www.cs.rpi.edu/~szymansk/OOF90/bugs.html
 
  • #4
O.k., one more piece of information...

...it has always been the case that when you pass a matrix to a subroutine, the subroutine needs to know (ahead of time or passed in at call time) the size of all the dimensions but the last one. You can pass or know the size of the last dimension, too, but it is not a must.

This has to do, of course, with the information the program need to access the matrix memory addresses.
 
  • #5
Thanks a lot guys !

This is just a toy program, in the actual program I have to (re)allocate inside the subroutine, so I can't pass the dimensions (because I don't know what they will be). The array is allocatable. I needed to make a (somewhat) realloc equivalent of C in FORTRAN.
I just made an interface and put it inside the program, as AlefZero said and it works ! And the link is useful too ! Thanks !
And thank you so much swartzism for the prompt reply !

And why are fortran errors so weird? If I miss an endif or a then after an if, it shows me an error in some unrelated loop...here also, it should have just told me at compile time that I needed to give it some sort of prototype for the subroutine before using it. :|
 
Last edited:
  • #6
Hhhmmm...I don't know about Fortran error message being weird. I have always found them pretty good...often time they even quote your line of code and another line below it showing with a caret exactly where the problem is.

Missing then? endif? Of course the problem is going to be reported somewhere else...try leaving a ' } ' out in C ...sooner or later and error will be reported and could very well be at the very end of the program when, finally, the brace count did not come down back to zero.

Unlike C, where all "sub-modules" are functions and require prototype, in Fortran we have functions and subroutines, typically, subroutines do not need a prototype. I am just making this comment but saying no more since I don't have experience with interfaces.

Anyway, just more commentary.
 

FAQ: FORTRAN-Passing array to subroutine-segmentation fault

What is FORTRAN?

FORTRAN, which stands for Formula Translation, is a high-level programming language commonly used for scientific and engineering applications. It was first developed in the 1950s and has undergone several revisions since then, with FORTRAN 77 and FORTRAN 90 being the most widely used versions.

2. What does it mean to pass an array to a subroutine?

Passing an array to a subroutine means giving the subroutine access to the elements of the array. This allows the subroutine to manipulate the array's data without having to copy the entire array, making the code more efficient.

3. What is a segmentation fault?

A segmentation fault, also known as a segfault, is an error that occurs when a program attempts to access memory that it does not have permission to access. This can happen when a program tries to access an invalid or non-existent memory address, leading to a program crash.

4. Why am I getting a segmentation fault when passing an array to a subroutine in FORTRAN?

There are several possible reasons for getting a segmentation fault when passing an array to a subroutine in FORTRAN. Some common causes include passing an array with an incorrect size or type, accessing an out-of-bounds element in the array, or using an uninitialized variable in the subroutine.

5. How can I fix a segmentation fault when passing an array to a subroutine in FORTRAN?

To fix a segmentation fault when passing an array to a subroutine in FORTRAN, you can check for common causes such as incorrect array size or type, out-of-bounds access, or uninitialized variables. You can also use debugging tools to identify the specific line of code causing the error and make necessary corrections. Additionally, using proper coding techniques such as array bounds checking can help prevent segmentation faults from occurring.

Similar threads

Replies
20
Views
3K
Replies
4
Views
2K
Replies
4
Views
2K
Replies
25
Views
2K
Replies
5
Views
7K
Replies
3
Views
2K
Replies
4
Views
3K
Back
Top