Fortran 77处理c++内存分配

Fortran 77 handling C++ memory allocations

本文关键字:分配 内存 c++ 77处理 Fortran      更新时间:2023-10-16

我正在尝试编写一个c++程序,它利用了数万行Fortran 77代码,但是遇到了一些奇怪的错误。我将三个坐标(x,y,z)和三个向量的地址从c++传递给fortran,然后让fortran在初始点上运行一些计算并返回三个向量的结果。

我在一个c++函数中这样做了几百次,离开那个函数,然后回来再做一次。它在第一次执行时工作得很好,但第二次执行时,对于x分量为正的点,它停止返回有用的结果(返回nan)。

最初看起来像是一个算法问题,除了三件事:

  1. 它工作完美的前200次我运行它
  2. 如果我从fortran中调用它并完全消除c++,它就会工作(对于最终程序不可行)
  3. 我试过在fortran中添加print语句来调试出错的地方,但事实证明,如果我将print语句添加到特定的子例程(甚至像print *,'Here'这样简单的东西),程序甚至在第一次运行时开始返回nan。

这就是为什么我认为这与如何在C和fortran函数/子程序调用之间分配和释放内存有关。基本设置是这样的:c++:

void GetPoints(void);

extern"C" { void getfield_(float*,float*,float*,float[],float[],float[],int*,int*); }

int main(void) { GetPoints(); //Works GetPoints(); //Doesn't }

void GetPoints(void) { float x,y,z; int i,n,l; l=50; n=1; x=y=z=0.0; float xx[l],yy[l],zz[l] for(i=0;i< l;我+ +)getfield_ (, x,, y,, z, xx, yy, zz,, n, l);//存储当前的xx,yy,zz在大的全局数组中}

Fortran:

      SUBROUTINE GETFIELD(XI,YI,ZI,XX,YY,ZZ,IIN,NP)
      DIMENSION XX(NP),YY(NP),ZZ(NP)
      EXTERNAL T89c
      T89c(XI,YI,ZI,XX,YY,ZZ)
      RETURN
      END
!In T89c.f SUBROUTINE T89c(XI,YI,ZI,XX,YY,ZZ) COMMON /STUFF/ ARRAY(100) !Lots of calculations !Calling ~20 other subroutines RETURN END

你们中有人看到我正在创建的任何明显的内存问题吗?也许fortran认为存在的通用块实际上被c++释放了?没有能力使用print语句进行调试,也没有时间去理解别人的几千行Fortran 77代码,我愿意尝试任何你们能建议或想到的方法。

我用g++ 4.5.1来编译c++代码和最终链接,用gfortran 4.5.1来编译fortran代码。

感谢

* *编辑:* *

我已经追踪到这个错误是在我出生前写的一些晦涩的代码。它似乎在寻找一些在多年的更新中被删除的常见变量。我不知道为什么它只影响一个维度,也不知道为什么通过添加print语句可以复制这个错误,但我已经消除了它。谢谢大家的帮助。

您可能会遇到"off-by- 1 "错误。Fortran数组是基于1的,而C数组是基于0的。请确保传入Fortran的数组大小不小于1。

编辑:

我想它看起来是对的…尽管如此,我还是会尝试在c++函数中分配51个元素,看看会发生什么。

顺便说一下,float xx[l];不是标准的。这是一个gcc特性。通常您应该在这里使用new分配内存,或者您应该使用std::vector

此外,我对循环中对getfield_的调用感到困惑。你不应该把i传递给getfield_吗?

您应该在子程序T89c中也将XX, YYZZ声明为数组,如下所示:

REAL*4 XX(*)    
REAL*4 YY(*)    
REAL*4 ZZ(*)

C/c++通常不应该释放任何Fortran公共块。这些类似于C中的structs(即内存在编译时保留,而不是在运行时保留)。

由于某种原因,gfortran似乎在T89c中接受以下内容,即使没有上面的声明:

print *,XX(1)

在编译过程中,但当执行它时,我得到一个分段错误。