Reputation: 1084
I am confused how Fortran handle the situation if the index for referencing an element of an array is actually out of its supposed range.
Here is a simple code to illustrate the problem:
PROGRAM test_matrix_out
USE mod_writearray
IMPLICIT NONE
INTEGER :: i,j,m,n
REAL :: k
REAL, Dimension(:,:),ALLOCATABLE :: A
m = 3
n = 4
ALLOCATE(A(m,n))
k = 1
DO i=1,m
DO j=1,n
A(i,j)=k
k=k+1
ENDDO
ENDDO
CALL writearray(A)
WRITE(*,*)
WRITE(*,*) A(1,:)
WRITE(*,*)
WRITE(*,*) A(2,:)
WRITE(*,*)
WRITE(*,*) A(0,:)
WRITE(*,*)
WRITE(*,*) A(4,:)
WRITE(*,*)
WRITE(*,*) A(5,:)
WRITE(*,*)
WRITE(*,*) A(100,:)
WRITE(*,*)
WRITE(*,*) A(:,1)
WRITE(*,*)
WRITE(*,*) A(:,2)
WRITE(*,*)
WRITE(*,*) A(:,0)
WRITE(*,*)
WRITE(*,*) A(:,4)
WRITE(*,*)
WRITE(*,*) A(:,5)
WRITE(*,*)
WRITE(*,*) A(:,100)
DEALLOCATE(A)
END PROGRAM test_matrix_out
It gives me the following result:
1.000000 2.000000 3.000000 4.000000
5.000000 6.000000 7.000000 8.000000
0.0000000E+00 9.000000 10.00000 11.00000
2.000000 3.000000 4.000000 0.0000000E+00
6.000000 7.000000 8.000000 0.0000000E+00
0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00
1.000000 5.000000 9.000000
2.000000 6.000000 10.00000
-1.0097448E-28 8.9776148E-39 0.0000000E+00
4.000000 8.000000 12.00000
0.0000000E+00 0.0000000E+00 0.0000000E+00
-3.3631163E-44 1.4293244E-43 0.0000000E+00
Why does this happen?
Upvotes: 4
Views: 3461
Reputation: 29381
When you write A(i,j) the compiler calculates the address of of that memory location. See, for example, http://en.wikipedia.org/wiki/Array_data_structure#Multidimensional_arrays. The compiler normally doesn't determine whether this is a legal address according to the rules of the language. Using indices past the dimensions is illegal. It is the responsibility of the programmer not to do this. One of the advantages of Fortran is the ability to add run-time checks for this mistake. The conventional lore is that run-time subscript checking is expensive but I when I have tested I have frequently found the runtime cost to be negligible and sometimes leave it on in production versions of programs.
If you are reading memory the likely consequence of an index mistake will be to obtain a wrong value, unless the memory location is so far off that it is outside the memory belonging to the program, which will create a fault. If you are writing to memory you will corrupt memory elsewhere in the array, belonging to some other variable, or belonging to an internal data structure of the program. See what kind of problems can lack of deallocation cause? for an example question where an index error caused runtime problems with a program.
Upvotes: 7
Reputation: 6241
What you are seeing is that the compiler you use to compile the program is not checking whether the arrays get out of bounds at run-time. So, depending on the compiler and machine, anything goes. At times, array elements that are not explicitly allocated in memory are possible to be referenced, which is what happens in your example. In this case, the value of the element that is out of bounds is whatever value is sitting at that memory address at program run-time. If the memory address requested does not exist or cannot be accessed, the program will fail with a segmentation fault.
I was just looking at the draft of the current Fortran standard, and I could not find any statement about whether accessing array elements out of bounds is a defined behaviour. In order to avoid these issues, compile your program with -C
(check bounds) flag. If possible, the program will let you know which element of which array went out of bounds. Use -C
during development, but not in production, because it slows down the code tremendously.
Also, for future reference, when asking questions of this kind (e.g. why my program outputs this?), it is best to include information about the compiler being used (with version number) and target architecture.
Upvotes: 5