Arrays 数组的索引超出范围
如果引用数组元素的索引实际上超出了其假定的范围,我不知道Fortran如何处理这种情况 下面是一个简单的代码来说明问题:Arrays 数组的索引超出范围,arrays,fortran,Arrays,Fortran,如果引用数组元素的索引实际上超出了其假定的范围,我不知道Fortran如何处理这种情况 下面是一个简单的代码来说明问题: 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
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
它给了我以下结果:
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
为什么会发生这种情况?您看到的是,用于编译程序的编译器没有检查数组在运行时是否越界。因此,根据编译器和机器,任何事情都会发生。有时,可能会引用未在内存中显式分配的数组元素,这就是示例中发生的情况。在这种情况下,超出边界的元素的值是程序运行时位于该内存地址的任何值。如果请求的内存地址不存在或无法访问,程序将因分段错误而失败 我只是在看当前Fortran标准的草案,我找不到任何关于越界访问数组元素是否是一种定义行为的陈述。为了避免这些问题,请使用
-C
(检查边界)标志编译程序。如果可能,程序会让您知道哪个数组的哪个元素超出了范围。在开发过程中使用-C
,但不要在生产中使用,因为这会大大降低代码的速度
此外,为了便于将来参考,在询问此类问题时(例如,为什么我的程序会输出此内容?),最好包含有关正在使用的编译器(版本号)和目标体系结构的信息。当您编写(i,j)时,编译器会计算该内存位置的地址。例如,请参见。编译器通常不会根据语言规则确定这是否是合法地址。使用超过维度的索引是非法的。程序员有责任不这样做。Fortran的优点之一是能够为这个错误添加运行时检查。传统的说法是运行时下标检查是昂贵的,但我在测试时经常发现运行时成本可以忽略不计,有时在程序的生产版本中保持不变
如果您正在读取内存,索引错误的可能后果将是获取错误的值,除非内存位置太远,以至于它位于属于程序的内存之外,这将产生故障。如果写入内存,则会损坏数组中其他位置的内存、属于其他变量或属于程序内部数据结构的内存。有关索引错误导致程序运行时出现问题的示例问题,请参见。标准不允许访问超出范围的数组元素,但不需要检查(Lagrange的阅读效果也不错)非常感谢大家!非常有用的评论@弗拉基米尔谢谢!很高兴知道。@VladimirF WG5文档现在位于自己的站点上,NAG FTP版本可能随时消失。新的URL是