Fortran 77处理c++内存分配
Fortran 77 handling C++ memory allocations
我正在尝试编写一个c++程序,它利用了数万行Fortran 77代码,但是遇到了一些奇怪的错误。我将三个坐标(x,y,z)和三个向量的地址从c++传递给fortran,然后让fortran在初始点上运行一些计算并返回三个向量的结果。
我在一个c++函数中这样做了几百次,离开那个函数,然后回来再做一次。它在第一次执行时工作得很好,但第二次执行时,对于x分量为正的点,它停止返回有用的结果(返回nan)。
最初看起来像是一个算法问题,除了三件事:
- 它工作完美的前200次我运行它
- 如果我从fortran中调用它并完全消除c++,它就会工作(对于最终程序不可行)
- 我试过在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
, YY
和ZZ
声明为数组,如下所示:
REAL*4 XX(*)
REAL*4 YY(*)
REAL*4 ZZ(*)
C/c++通常不应该释放任何Fortran公共块。这些类似于C中的structs
(即内存在编译时保留,而不是在运行时保留)。
由于某种原因,gfortran似乎在T89c
中接受以下内容,即使没有上面的声明:
print *,XX(1)
在编译过程中,但当执行它时,我得到一个分段错误。
- 在c++中为我自己的基于指针的数组分配内存的正确方法
- 给定一个指向堆分配内存的指针,智能指针实现如何为其找到合适的释放函数?
- 如果 const 不分配内存,为什么我可以获取 const 的地址?
- 在函数中分配内存时出现问题
- 如何为 std::vector 分配内存,然后稍后为某些元素调用构造函数?
- constexpr new 如何分配内存?
- 在构造函数中分配内存失败是如何冒泡的
- LLVM 传递以在特定地址分配内存
- CudaMalloc 在分配内存时失败
- 为什么它在不分配内存的情况下工作正常
- 为什么在正确解除分配内存时出现内存泄漏?
- 如何通过 malloc 为队列数组分配内存?
- vector是否为std::移动的对象连续分配内存
- 删除类成员的动态分配内存的最佳方法是什么
- 唯一指针是否在堆或堆栈上分配内存?
- 如果不分配内存,我如何能够为变量创建和分配值?
- std::initializer_list 堆是否分配内存?
- 如何按顺序或在指定的地址分配内存?
- 是否可以使用 malloc 为类对象分配内存?
- 迭代器是否分配内存(如指针)?