英特尔FORTRAN中的DEALLOCATE

时间:2013-03-21 17:31:33

标签: fortran

使用现有的FORTRAN代码时发现了一个问题。虽然它已经预见到在重新分配之前需要释放数组,但这从来没有必要。我现在需要它来做这件事,它没有正常运作。

当前的伪代码大约是:

MODULE mA
  TYPE A
    REAL, DIMENSION(:,:,:), ALLOCATABLE :: array
  END TYPE
  TYPE (A), POINTER :: sw(:)
END MODULE

稍后,有一些代码会分配'数组'的大小,我现在正在调用两次(迄今为止只有一次):

...
IF (ALLOCATED(sw(1)%array))  DEALLOCATE(sw(1)%array, STAT=aviFail)

IF (aviFail.EQ.0) ALLOCATE(sw(1)%array(1,2,3), STAT=aviFail)
...

我已经查看了ALLOCATE,DEALLOCATE和ALLOCATED的定义,我发现了以下内容:

  1. 第二次通过,调用DEALLOCATE,但STAT值为' 1'
  2. 如果失败(即STAT返回正),则DEALLOCATE意味着保持原始数组不变。它没有:它显然正确地清除它(至少,根据调试器)。
  3. 如果失败并且没有定义STAT,则DEALLOCATE意味着终止程序。它没有,但以下ALLOCATE语句失败,STAT值为' 1'。
  4. 我还在其他地方无意中在同一阵列上调用了ALLOCATE两次,而没有首先进行DEALLOCATING。根据这本书,这应该导致程序终止。它不仅有效,而且工作正常,第二个ALLOCATE的STAT返回是' 0'。

    英特尔FORTRAN是否以不同的方式处理这些问题,或者FORTRAN对于实现其C ++规范并不是那么挑剔?

1 个答案:

答案 0 :(得分:3)

没有看到更多的实施,很难给出详细的&有针对性的解释,但我认为它可能是导致你的问题的指针的实现。你给出的关于ALLOCATE和DEALLOCATE的行为的“书”回答是正确的,但是你描述了直接使用可分配数组时它们的行为方式。在对指针进行操作时,ALLOCATE和DEALLOCATE的功能可能不同(依赖于编译器)。在最基本的层面上,通过指针分配内存需要更多步骤:1)确定要为指针创建的对象的类型/维度,2)在内存中创建和分配该类型/维度的未命名对象,3)关联带有新对象的指针。根据实现,编译器和其他因素,这些额外的步骤可能会增加程序观察到的行为的复杂性。

在此实现中使用指针是否有特殊原因?如果没有,我建议切换到一个更简单的普通可分配数组,看看问题是否仍然存在。

关于你能够错误地ALLOCATE和数组两次没有预期的程序终止:我认为这也与使用指针的实现有关。您重新分配的指针已与内存中的位置相关联。这种关联可能会改变编译器在第二次执行时处理ALLOCATE语句的方式。如果指针已经与具有ALLOCATE语句要求的维度的内存位置相关联,则没有理由终止程序或抛出错误;程序员正在得到他或她要求的内容。

最后,ALLOCATE / DEALLOCATE语句和指针关联/无效由不同的编译器以不同的方式处理,因此您的观察行为不符合“本书”并不奇怪。我建议你看看你是否真的需要指针实现,并确保在编码时应用内存管理最佳实践。