Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
“英特尔Fortran错误”;“未分配可分配数组或指针”;_Fortran_Intel Fortran - Fatal编程技术网

“英特尔Fortran错误”;“未分配可分配数组或指针”;

“英特尔Fortran错误”;“未分配可分配数组或指针”;,fortran,intel-fortran,Fortran,Intel Fortran,当我试图运行一个巨大的Fortran代码(该代码是使用英特尔编译器13.1.3.192版编译的)时,它给了我如下错误消息: ... Info[FDFI_Setup]: HPDF code version number is 1.00246 forrtl: severe (153): allocatable array or pointer is not allocated Image PC Routine Line

当我试图运行一个巨大的Fortran代码(该代码是使用英特尔编译器13.1.3.192版编译的)时,它给了我如下错误消息:

... 
Info[FDFI_Setup]: HPDF code version number is  1.00246
forrtl: severe (153): allocatable array or pointer is not allocated
Image              PC                Routine            Line        Source
arts               0000000002AD96BE  Unknown               Unknown  Unknown
arts               0000000002AD8156  Unknown               Unknown  Unknown
arts               0000000002A87532  Unknown               Unknown  Unknown
...
尽管如此,如果我在其中一个子例程中插入一个小的write语句(这只是为了检查代码,而不是干扰代码的原始用途),如下所示(我无法放置所有代码,因为它们太大):

然后,上面显示的错误消息突然消失,代码可以正常运行!我还试图在源代码的其他位置插入这样的write语句,但上面的错误消息仍然存在

根据:

严重(153):未分配可分配数组或指针 只需$IOS_invdealoc。尝试取消分配Fortran 90可分配数组或指针时,必须已分配该数组或指针。必须先分配数组或指针,然后才能再次释放它。 注意:STAT可以在DEALLOCATE语句中返回此错误

但是,我看不到错误与我添加到代码中的“write语句”之间的任何关系。在我添加write语句的位置没有这样的“allocate”命令

所以我很困惑。有人知道原因吗?非常感谢您的帮助

使用回溯选项,我可以直接找到错误源:

    subroutine StringRead(Str,delimiter,StrArray,ns)   ! [private] read strings separated by    delimiter
    implicit none
    character*(*),intent(in)    :: Str
    character*(*),intent(in)    :: delimiter
    character*(*),pointer       :: StrArray(:)
    integer,intent(out)         :: ns
! - local variables
    character(len=len(Str))     :: tline
    integer                     :: nvalue,nvalue_max
    character(len=len(StrArray)),pointer:: sarray(:),sarray_bak(:)
    integer                     :: len_a,len_d,i

    ! deallocate StrArray
    if(associated(StrArray)) deallocate(StrArray)

根据回溯给我的信息,错误在上面显示的最后一条语句中。如果我注释掉这个语句,那么“forrtl:severe(153)”错误将在生成新错误时消失。。。但是,我仍然不认为这句话本身会出错…它的行为就像它忽略了如果。。。条件并直接读取解除分配命令,这在我看来很奇怪。

您可能有一个错误,其中您非法写入内存并损坏存储分配信息的结构。更改代码可能会导致内存损坏发生在其他地方,并且该特定错误会消失。通常,在Fortran中,非法内存访问通常以两种方式发生。1) 非法下标,2)实际参数和伪参数之间的不匹配,即调用中的变量和过程中声明的变量之间的不匹配。您可以使用编译器的运行时下标检查选项来搜索第一类错误。您可以通过将所有过程放在模块中并
使用这些模块来防止出现第二种情况,这样编译器就可以检查参数的一致性。

听起来像是前面的一些注释给出了一般性解释。但是,

1) StrArray(:)是故意的吗?也就是说,您是否正在将文件的行读入s/r中的StrArray(),希望将其作为文件内容返回?如果是这样的话,就把它声明为一个(出局),或者不管它应该是什么

2) 为什么StrArray()是指针?它需要是指针吗?如果您只需要文件内容,那么最好使用非指针

您可能仍然需要一个可分配的、自动的或其他的,但是在许多情况下非指针更容易

3) 如果必须将StrArray(:)作为指针,则必须在使用之前创建其大小/形状等。如果正确定义了调用序列ACTUAL Arg(如果StrArray()是Intent(In)或Intent(InOUT),则可能会这样做

相反,如果它是一个(Out),那么与所有指针数组一样,它必须首先在s/r中使用allcoating()

如果它在早期没有分配到某个位置,那么它是未定义的,因此DeAllocate()将失败,因为它没有要DeAlloc的内容,因此Stat=153

4) 您可能希望在不知道要读取的行数的情况下使用它来读取文件。在这种情况下,您不能(至少不容易)提前分配StrArray(),因为您不知道大小。在这种情况下,需要其他策略

一个可能的解决方案是一个循环,简单地读取文件中每一行的第一个字符,或者以某种方式前进。让循环跟踪每行读取的“和”,直到EOF。然后,您将知道文件的大小(以num行为单位),然后分配StrArray(SumLines)或其他内容。差不多

SumLines = 0
Do i=1, ?? (or use a While)
    ... test to see if "line i" exists, or EOF, if so, Exit
    SumLines = SumLines + 1
End Do
最好在单独的s/r中执行此操作,以便在调用FileRead位之前知道大小等(即,在FileRead s/r调用之前设置文件大小)

然而,这仍然给您留下了使用什么字符(Len)的问题。有许多可能的解决办法。其中三项是:

a) 使用最大长度,比如Character(Len=2048)、Intent(Out),或者更好的是,使用一些编译时常量参数,称之为MaxLineWidth


这对编译器给OP的错误消息中的行有明显的限制,我建议查找可能无法到达的任何分配语句(取决于条件)。您可能正在取消分配或分配未分配的数组。事实上,
write
语句与错误无关,它只是在未分配内存时更改写入内存的位置,现在它发生在不会造成损坏的位置。不过,这并不是一个永久性的解决方案,因为根据运行代码时机器的状态,错误可能会或不会再次出现。非常感谢上述建议。我有一个问题,如何应用“-traceback”编译器选项?在代码的主要部分,它在调试标志中使用了-traceback以及其他选项。然而,在代码的其他部分中,没有这样的调试标志。所以,我想知道一般如何使用这个编译器选项?我尝试过类似“make-f Makefile-d-trackback”这样的方法,但它不起作用……更新:我刚刚找到了将trackback放入其中的方法:make“FLAGS=-trackback”……谢谢你。但是,我看不到错误和我添加到代码中的“write语句”之间的任何关系。正如其他人所说的那样
SumLines = 0
Do i=1, ?? (or use a While)
    ... test to see if "line i" exists, or EOF, if so, Exit
    SumLines = SumLines + 1
End Do
Type MyFileType
    Character(Len=1), Allocatable   :: FileLine(:)  ! this give variable length lines, but each "line" must be allocated to the length of the line
End Type MyFileType
Type(MyFileType), Allocatable   :: MyFile(:)    ! or, instead of Allocatable, can use Automatic etc etc