我正在尝试编写一个使用数万行 Fortran 77 代码的 C++ 程序,但遇到了一些奇怪的错误。我将三个坐标 (x,y,z) 和三个向量的地址从 C++ 传递到 fortran,然后让 fortran 在初始点上运行一些计算并在三个向量中返回结果。
我在一个 C++ 函数中这样做了几百次,离开那个函数,然后再回来做。它第一次完美运行,但第二次停止返回有用的结果(返回 nan),用于具有正 x 分量的点。
最初它似乎是一个算法问题,除了三件事:
- 我运行它的前 200 次它运行良好
- 如果我从 fortran 调用它并完全消除 C++,它就可以工作(对于最终程序不可行)
- 我尝试将打印语句添加到 fortran 以调试出错的地方,但事实证明,如果我将打印语句添加到特定的子例程(甚至像 PRINT *,'Here' 这样简单的东西),程序甚至在第一次运行。
这就是为什么我认为这与 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;i++)
getfield_(&x,&y,&z,xx,yy,zz,&n,&l);
//Store current xx,yy,zz in large global array
}
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++ 释放的常见块?没有使用打印语句进行调试的能力,也没有时间尝试理解别人的几千行 Fortran 77 代码,我愿意尝试任何你们可以建议或想到的任何事情。
我使用 g++ 4.5.1 编译 C++ 代码和最终链接,使用 gfortran 4.5.1 编译 fortran 代码。
谢谢
**编辑:**
我已经将错误追溯到我出生之前编写的一些晦涩的代码片段。它似乎正在寻找多年来在更新中删除的一些常见变量。我不知道为什么它只影响一个维度,也不知道为什么通过添加打印语句可以复制该错误,但我仍然消除了它。谢谢大家的帮助。