从Fortran调用的子程序C ++:如何处理动态内存分配?

时间:2014-05-07 11:30:21

标签: c++ arrays memory-management fortran

我目前有一个C ++程序执行一些任务(这里不重要),并将一些数据存储到已动态分配的2D数组中(使用C函数malloc)。它工作得很好,我现在需要在fortran程序中访问这些数据。我目前正在Fortran中创建一个程序,它在C / C ++中调用子程序来执行我想要的任务,但是当2D动态数组充满数据时,我需要在返回Fortran主程序时访问它。 问题是我无法将数据恢复到Fortran主程序(在2D可分配数组中) 我试图编写一个简单的程序,用于传递在C子程序中分配的动态数组,该子程序由我的主Fortran程序调用,以便在我离开C子程序时查看是否可以访问数据。

这是我的小代码:

Fortran主要:

PROGRAM FORT_C

use iso_c_binding
IMPLICIT NONE

interface
    subroutine call_fc(pX,s) bind(C,name='call_fc_')
        import
        integer(c_int)              :: s
        type(c_ptr), allocatable    :: pX
    end subroutine
end interface

integer(c_int)                              :: i
integer(c_int), pointer                     :: X(:)
type(C_ptr), allocatable                    :: pX


call call_fc(pX,100)
call c_f_pointer(pX,X,[100])

END

C子程序:

#include <cstdlib>
#include <iostream>

using namespace std;

extern "C" 
{
    void call_fc_(int **x, int s);
    void c_func_deallocate(int **x);
}


void call_fc_(int **x, int s)
{
    int i;
    *x = (int *) malloc(sizeof(int)*s);
    for(i=0;i<100;i++)
    {
        cout << i << endl;
        *x[i]=i;
    }
}

void c_func_deallocate(int **x)
{
    free(*x);
}

这很简单,但我得到输出:

0
1
forrtl: severe (174): SIGSEGV, segmentation fault occurred
Image              PC                Routine            Line        Source             
exemple            000000000040304C  Unknown               Unknown  Unknown
exemple            0000000000402F25  Unknown               Unknown  Unknown
exemple            0000000000402ECC  Unknown               Unknown  Unknown
libc.so.6          000000331241ECDD  Unknown               Unknown  Unknown
exemple            0000000000402DC9  Unknown               Unknown  Unknown

我不明白为什么我会在i> 1时得到这个 我希望我对自己的问题很清楚,有人可以帮忙吗?

非常感谢!

2 个答案:

答案 0 :(得分:2)

您的问题是*x[i]=i;表示*(x[i])=i;,但您想要的是(*x)[i]=i;

这是因为x[i]*x都指向int,因此编译器无法捕获错误。
*x[i]相当于x[i][0],而(*x)[i]相当于x[0][i]。)

为了避免这个问题和括号,您可以像这样重写:

void call_fc_(int **x, int s)
{
    int i;
    int *y = (int *) malloc(sizeof(int)*s);
    for(i = 0; i < 100 && i < s; i++)
    {
        cout << i << endl;
        y[i]=i;
    }
    *x = y;
}

我为i < s添加了一个测试,以避免在数组外写字。

答案 1 :(得分:2)

除此之外,Fortran中用于C ++函数的接口声明pX参数是可分配的。注意对此的支持需要一个支持未来F201X标准的该功能的编译器。其中很多都没有。

我非常怀疑这不是你想要的 - 但如果你做了C ++参数声明与你所拥有的完全不同。有关更多信息,请咨询TS以获得与C的进一步互操作性。

您不需要或希望pX可分配,无论是作为主程序中的变量还是参数。你不是&#34;分配&#34; pX - 您要使用C ++函数分配的某些内存的C地址定义C_PTR。

此外,声明接口中的s参数没有VALUE属性。这意味着它对应于C端的指针参数。您的C定义显示它是按值传递的。