Arrays fortran检查器的内存访问无效

Arrays fortran检查器的内存访问无效,arrays,memory,fortran,inspector,Arrays,Memory,Fortran,Inspector,如果我用数组运行fortran程序,我会得到错误的计算值(请看代码)。如果我使用intel inspector(-mi3),它会告诉我每次在程序中使用一个大阵列时都会出现内存问题“无效内存访问”,并且在/lib64/ld-linux-x86-64.so.2中也会出现错误。 首先,我认为我没有足够的内存空间,但在我的64位机器上,有16 GB内存,有足够的内存空间(:free-m~14 GB)。 如果我估计我的程序的内存大小,大约4GB就足够了。当我的程序运行时,使用的内存从0%增加到~20%,并

如果我用数组运行fortran程序,我会得到错误的计算值(请看代码)。如果我使用intel inspector(-mi3),它会告诉我每次在程序中使用一个大阵列时都会出现内存问题“无效内存访问”,并且在/lib64/ld-linux-x86-64.so.2中也会出现错误。 首先,我认为我没有足够的内存空间,但在我的64位机器上,有16 GB内存,有足够的内存空间(:free-m~14 GB)。 如果我估计我的程序的内存大小,大约4GB就足够了。当我的程序运行时,使用的内存从0%增加到~20%,并在那里停止,直到程序“正常”终止。所以我想我有足够的记忆空间。对于小型阵列(例如nemax=3 000 000),我在英特尔inspector中获得正确的计算值,并且没有错误。我还使用标志check all检查了数组。 我使用ifort-mcmodel=medium-shared intel-o test.f90编译程序。 我不知道我还能做些什么来解决这些内存访问错误?有人有主意吗?? 谢谢你的帮助

  module lz_data

  integer,parameter :: maxsite=16   
  integer,parameter :: nmax =6000000 
  integer,parameter :: nemax=300000000

  real*8,save :: diag(nmax)        

  real*8,save  :: werte(nemax)              !Here are the only large arrays
  integer,save :: izeile(nemax)
  integer,save :: ispalt(nemax)

  integer,save :: nentry

  end module lz_data

  prgram test
  use lz_data

  implicit real*8 (a-h,o-z)
  real*8 umat(maxsite,maxsite)
  logical lav(nmax,maxsite) 
  logical lbv(nmax,maxsite) 

  ...

  do is=1,ns
    diag(is)=0.0d0    ! HERE the debugging tool says invalid memory access 
    do i=1,msite
      do j=1,msite
        if (lav(is,i).and.lbv(is,j)) diag(is)=diag(is)+umat(i,j) ! invalid memory access
      enddo
    enddo
  enddo

看起来您遇到了一些静态数组大小限制。mcmodel=medium“应该”有帮助,但显然没有。您可以用可分配数组替换大型静态数组,看看这是否有帮助


哦,就像高性能Mark所说的,使用隐式无,确保初始化所有变量,并提供一个自包含的示例代码。

除了其他出色的建议外,我建议编译时启用尽可能多的调试选项,包括运行时错误检查。编译器将为您提供有关可能导致错误的错误实践的警告,并将查找其他错误。错误做法包括未声明或未初始化的变量。我建议不要使用隐式类型并声明每个变量。通过运行时下标检查,编译器将在下标超出数组边界时通知您。。。比无效内存访问更容易理解的错误。使用英特尔ifort try:
-O2-支架f03-假设realloc\u lhs-全部检查-回溯-全部警告-fstack protector-假设保护\u parens-隐式

在编辑代码示例以使其能够使用这些选项强制执行的规则干净地编译之后,运行会显示错误消息:

forrtl: severe (193): Run-Time Check Failure. The variable '_test_$NS' is being used without being defined

i、 例如,ifort在运行时查找未斜体的变量。这导致程序在数组末尾运行并访问无效内存。

除其他建议外,您还应确保shell中的默认堆栈大小限制不会影响您。静态数组通常在堆栈上创建,BASH中的默认堆栈大小为8Mb。如果您的数组大于此值,则最终会导致访问冲突。您可以通过设置

ulimit -s unlimited

在BASH中,堆栈大小仅受系统中可用内存的限制。

谢谢您的帮助!我已经将ulimit-s设置为无限或10GB。我知道使用隐式不是很好,但是对于较小的系统,我的程序运行得非常好,所以为什么使用隐式会出现错误呢。我希望使用可分配数组而不是大型静态数组,但在我的例子中,这没有意义,因为大型数组werte值的计算与数组的范围有关。因此,我不得不浪费一点(!)内存来预测静态数组的足够维数。在我的例子中,预测维度并不复杂,我绝对(100%)确信计算出的数组适合静态数组。我甚至用-全选旗来检查。我可以用diag(nmax)数组创建一个可分配的数组,因此我将对此进行检查,但是这个数组远没有werte(nemax)数组大

您已经显式地使用了隐式类型。然后使用未声明和未初始化的变量,如
is
ns
msite
来控制循环。如果您没有初始化
ns
,则
diag(is)
引用无效的内存位置对我来说并不奇怪。请不要告诉我你忽略了这些变量的声明和初始化,当我能看到所有这些时,调试别人的代码就足够困难了,隐藏基本行是非常糟糕的运动。谢谢你的评论,但是为什么我的变量没有声明呢。如果我使用隐式实数*8(a-h,o-z),所有以I-n开头的变量都是整数。与其说它们是否声明,不如告诉我们它们的初始化位置和初始化值。谢谢您的帮助!我已经设置了ulimit-s unlimited。使用隐式类型不一定是错误的,但它会使代码更难理解,并且有产生棘手错误的风险。使用
implicit none
以(现在)非常小的成本提供了巨大的好处,特别是因为您明确声明了大多数变量的类型和种类。另外,您对可分配数组有何异议?只要阵列的大小需要更改或在运行时才知道,它们都非常方便。