0

Here, I know that A is just a 1D array of length 170.

subroutine gonewrong(q,e,A)

implicit none

integer, dimension(:) :: q

integer, dimension(:,:), intent(in) :: e

integer, dimension(size(e,1)*2), intent(out) :: A
print *, A(2)
end subroutine gonewrong

When I try to find A(2), for example, it gives me a segmentation fault! e has dimension (85,2).

Would it be because I declared A as an allocatable array in the program I used to compile it with?

The program I used:

program prog_1
use module_1
implicit none
integer::qm,a,b,c
integer,allocatable,dimension(:)::q
integer,allocatable,dimension(:,:)::e
!integer, dimension(size(e,1)*2) :: A
a = 5
b = 3
c = 10
allocate(q(a+c))
allocate(e(a+b*c,2))

call subr1(a,b,c,qm,q,e) !Outputs are qm,q and e.
call gonewrong(q,e,A) !gonewrong takes q and e as arguments
end program prog_1
11
  • You must show more code! It should be compilable. We must see how you are calling it and how does the program see the interface. Is the subroutine in a module? It should be! Commented Dec 11, 2016 at 16:07
  • @VladimirF Yes, it is in a module and compiles. I've edited. Commented Dec 11, 2016 at 16:16
  • Wait, how can you have A as a scalar integer in the program and then pass it to the subroutine which expects an array? How can that ever compile? Show the complete code, the whole module, the commands you use. Compile with some debugging flags (-g -fcheck=all -Wall). Commented Dec 11, 2016 at 16:27
  • 1
    a and A is the same thing!!! Commented Dec 11, 2016 at 16:52
  • 1
    A is not declared anything, the line is commented out. Or it was just a minute ago. With both declaration for a and A it can't compile. Don't make random changes to the code in the question when people take it as a base for their answers. Make sure the code is exactly the code you tested. Commented Dec 11, 2016 at 16:57

2 Answers 2

1

Another issue to consider is that in the declaration:

integer,allocatable,dimension(:,:)::e
integer, dimension(size(e,1)*2) :: A

the size of e is undefined (zero?) at the time A is declared. If the size of A depends on the size of e, you'll need to either fix the size of e at compile time or set A to be allocatable and separately allocate it once the size of e has been set. The takeaway is that A won't dynamically adjust its size as the size of e changes. In this case, it looks like A is declared with zero length because size(e) returns zero because only the shape of e has been defined, not its size. Referencing A(2) would likely throw a segmentation violation (reading off the end of the array) which would be consistent with what you're observing.

Aside: Many people coming to Fortran from dynamic languages don't realize that Fortran routines are split into at least three "zones"; an initial section containing use statements for importing external resources, a declaration section where arguments and local variables are declared, and the body of the routine where executable statements are placed (pedants are encouraged to read the language spec; I'm generalizing here for pragmatism's sake). The implicit statement separates the imports from the declarations, and by convention, I separate declarations from executable statements with a bare continue statement. continue is considered executable, so the compiler should complain if declarations appear after this first continue.

Sign up to request clarification or add additional context in comments.

1 Comment

As I commented, this is caused by the OP changing his code in the question without caring. I will revert it to the sensible state.
0

The error is quite clear:

integer::qm,a

makes a a single integer number (scalar).

The subroutine requires an array:

integer, dimension(size(e,1)*2), intent(out) :: A

So you are passing the wrong thing there in:

call gonewrong(q,e,A) !gonewrong takes q and e as arguments

because Fortran is case insensitive! You are passing the scalar integer a/A to the subroutine which expects an array.

It is much better to use the same (:) inside the subroutine for A and let the compiler tell you that you are making an error.

The argument is an array so you must pass an array there.

Note: in your original code you had this line commented out

! integer, dimension(size(e,1)*2) :: A

when you have both lines

integer::qm,a
integer, dimension(size(e,1)*2) :: A

the program will not compile because a/A is declared twice.


What less clear to me is your actual intention. Your comment

!gonewrong takes q and e as arguments

is really confusing. All three things are arguments of gonewrong. q, e and A.

2 Comments

Great thank you, I have fixed the case error and changed a to L.
There is no case error... Fortran/FORTRAN is case insensitive, so there is no possibility for a case error other than believing that there is the concept of case.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.