fortran中的数组negtivel索引的调试错误

时间:2012-01-28 21:40:36

标签: fortran95

我在这里有一个测试程序:

  program test  
  implicit none  

  integer(4) :: indp  
  integer(4) :: t1(80)  

  indp = -3  
  t1(indp) = 1  
  write(*,*) t1(indp)  

  end program test
在第8行

是错误的,因为indp是负数。但是当我编译它时使用'ifort'或'gfortran'它们都找不到这个错误。 甚至使用valgrind来调试这个程序它也找不到这个错误。 你有什么想法找到这种问题吗?

2 个答案:

答案 0 :(得分:6)

Fortran编译器不需要向您发出有关此类内容的警告;通常,如果将fortran数组的下限设置为等于或小于-3的值,则t1(-3)= 1可能是一个非常合理的语句,例如

integer(kind=4), dimension(-5:74) :: t1(80)

肯定会允许设置和读取t1(-3)。

如果要确保在运行时检查这些类型的错误,可以使用gfortran与-fbounds-check进行编译:

$ gfortran -o foo foo.f90 -fcheck=bounds
$ ./foo 
At line 8 of file foo.f90
Fortran runtime error: Array reference out of bounds for array 't1', lower bound of dimension 1 exceeded (-3 < 1)
在ifort中

-check bounds

ifort -o foo foo.f90 -check bounds

$ ifort -o foo foo.f90 -check bounds
$ ./foo
forrtl: severe (408): fort: (3): Subscript #1 of the array T1 has value -3 which is less than the lower bound of 1

Image              PC                Routine            Line        Source             
foo                000000000046A8DA  Unknown               Unknown  Unknown

valgrind没有捕到这个的原因有点微妙,但请注意,如果分配了数组,那就是:

  program test  
  implicit none  

  integer(kind=4) :: indp  
  integer(kind=4), allocatable :: t1(:)  

  indp = -3  
  allocate(t1(80))
  t1(indp) = 1  
  write(*,*) t1(indp)  
  deallocate(t1)

  end program test

$ gfortran -o foo foo.f90 -g
$ valgrind ./foo
==18904== Memcheck, a memory error detector
==18904== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==18904== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
==18904== Command: ./foo
==18904== 
==18904== Invalid write of size 4
==18904==    at 0x400931: MAIN__ (foo.f90:9)
==18904==    by 0x400A52: main (foo.f90:13)
==18904==  Address 0x5bb3420 is 16 bytes before a block of size 320 alloc'd
==18904==    at 0x4C264B2: malloc (vg_replace_malloc.c:236)
==18904==    by 0x400904: MAIN__ (foo.f90:8)
==18904==    by 0x400A52: main (foo.f90:13)
==18904== 
==18904== Invalid read of size 4
==18904==    at 0x4F07368: extract_int (write.c:450)
==18904==    by 0x4F08171: write_integer (write.c:1260)
==18904==    by 0x4F0BBAE: _gfortrani_list_formatted_write (write.c:1553)
==18904==    by 0x40099F: MAIN__ (foo.f90:10)
==18904==    by 0x400A52: main (foo.f90:13)
==18904==  Address 0x5bb3420 is 16 bytes before a block of size 320 alloc'd
==18904==    at 0x4C264B2: malloc (vg_replace_malloc.c:236)
==18904==    by 0x400904: MAIN__ (foo.f90:8)
==18904==    by 0x400A52: main (foo.f90:13)

答案 1 :(得分:1)

没有错误。您将indp声明为某个范围和精度的整数(某个 KIND < - 在该术语的帮助中查找),可以是正数也可以是负数。

之后,您将1的值分配给t1(indp)并将其写出来。