Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
27 Views

CPP calls FORTRAN

Hello!

I have a problem with the mixed languages programming.

This is a task with the cpp/fortran pointers passing when the 2d dynamic array was created.

Main CPP program is calling FORTRAN array filling subroutine. Can't get the right results, please help.

PS I can't using an one-dimensional array, like this arr[i*N +j] :(

 

CPP TEXT:

#include <cstdlib>
#include <iostream>

using namespace std;

extern "C" void fill_array(int **, int, int);
int main()
{
    int i, j, N, M;
    int **arr;
    cout<<endl<<"rows Number  ="<<endl;    cin>>M;
    cout<<endl<<"cols Number  ="<<endl;    cin>>N;
    cout<<endl;
    arr = new int*;
    for(int i = 0; i < N; i++)arr = new int;
//
    fill_array(arr,M,N);
//    
    for( i = 0; i < N; i++)
    {   
      for( j = 0; j < M; j++)
      {  
         cout << arr<<" ";
      }
      cout<<endl;
    }  
//    
    for( i = 0; i < N; i++)delete [] arr;
    delete [] arr;

    return EXIT_SUCCESS;
}

FORTRAN TEXT:

SUBROUTINE FILL_ARRAY(C,M,N)BIND(C,name="fill_array")
    USE, INTRINSIC                         :: ISO_C_BINDING
    INTEGER(KIND=C_INT), INTENT(IN), VALUE :: N,M
    TYPE(C_PTR)                            :: C
    INTEGER(C_INT), POINTER      :: F(:,:)
    INTEGER                                  :: I,J, RANK
    RANK = N*M
    CALL C_F_POINTER(C,F,[RANK])
    DO I=1, M
        DO J = 1, N
            F(I, J) = I + J
        ENDDO
    ENDDO
END SUBROUTINE    

Typical output for matrix 3x3 is not correct:

2 3 4

0 3 4

0 0 4

0 Kudos
6 Replies
Highlighted
27 Views

Fortran allocated arrays are contiguous. Your C++ code first allocates an array of int pointers, then allocates to each pointer a row of data. These rows are not contiguous.

What you should do is after allocating the C++ array of int pointers, allocate a buffer of int, size M*N integers, then construct the pointers into this contiguous buffer, and insert them into your int** array. The base of this array is passed to Fortran (plus M and N). From these you can construct a proper pointer to use as F.

To construct a proper value for F use

 CALL C_F_POINTER(C,F,[M,N]) ! or N,M

or

INTEGER :: RANK(2) ! 1D integer array
...
RANK = [M,N] ! or [N,M] ! populate with [columns, rows]
 CALL C_F_POINTER(C,F,RANK)

And when (if) you later delete the data, you do not delete the individual rows, instead delete the blob of data, followed by the array of int*'s.

Jim Dempsey

0 Kudos
Highlighted
27 Views

Thank you Jim for your detailed explanation!

I have made all of you recommendation you noted,

for cpp code

#include <cstdlib>
#include <iostream>

using namespace std;

extern "C" void fill_array(int **, int, int);
int main()
{
    int i,j,N, M;
    int **arr, *buf;
    cout<<endl<<"rows Number  ="<<endl;    cin>>M;
    cout<<endl<<"cols Number  ="<<endl;    cin>>N;
    cout<<endl;
    arr = new int*;
    buf = new int[M*N];
            
    for( i = 0; i < M; i++)arr = &buf[N*i];
//
    fill_array(arr,M,N);
//    
    for( i = 0; i < N; i++)
    {   
      for( j = 0; j < M; j++)
      {  
         cout << arr<<" ";
      }
      cout<<endl;
    }  
//    
    delete[] buf;
    delete [] *arr;

    return EXIT_SUCCESS;
}

and FORTRAN

SUBROUTINE FILL_ARRAY(C,M,N)BIND(C,name="fill_array")
    USE, INTRINSIC                         :: ISO_C_BINDING
    INTEGER(KIND=C_INT), INTENT(IN), VALUE :: N,M
    TYPE(C_PTR)                            :: C
    INTEGER(C_INT), POINTER                :: F(:,:)
    INTEGER                                :: RANK(2)
    RANK = [M,N]
    CALL C_F_POINTER(C,F,RANK)
    DO I=1, M
        DO J = 1, N
            F(I, J) = I + J
        ENDDO
    ENDDO
END SUBROUTINE    

Correct results , but the problem still exists...in the new messages, maybe incorrect at the pointers deleting?

rows Number  =
3

cols Number  =
3

2 3 4
3 4 5
4 5 6
*** Error in `/home/mmax/DevStudioProjects/LABcpp/dist/Debug/Intel-Linux/labcpp': double free or corruption (fasttop): 0x000000000116e030 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x816b9)[0x7f8f1d7136b9]
/home/mmax/DevStudioProjects/LABcpp/dist/Debug/Intel-Linux/labcpp[0x400e68]
/lib64/libc.so.6(__libc_start_main+0xf5)[0x7f8f1d6b4545]
/home/mmax/DevStudioProjects/LABcpp/dist/Debug/Intel-Linux/labcpp[0x400ac9]
======= Memory map: ========
00400000-00403000 r-xp 00000000 fd:02 1073927361                         /home/mmax/DevStudioProjects/LABcpp/dist/Debug/Intel-Linux/labcpp
00602000-00603000 r--p 00002000 fd:02 1073927361                         /home/mmax/DevStudioProjects/LABcpp/dist/Debug/Intel-Linux/labcpp
00603000-00604000 rw-p 00003000 fd:02 1073927361                         /home/mmax/DevStudioProjects/LABcpp/dist/Debug/Intel-Linux/labcpp
0116e000-0118f000 rw-p 00000000 00:00 0                                  [heap]
7f8f18000000-7f8f18021000 rw-p 00000000 00:00 0
7f8f18021000-7f8f1c000000 ---p 00000000 00:00 0
7f8f1d48e000-7f8f1d490000 r-xp 00000000 fd:00 67311862                   /usr/lib64/libdl-2.17.so
7f8f1d490000-7f8f1d690000 ---p 00002000 fd:00 67311862                   /usr/lib64/libdl-2.17.so
7f8f1d690000-7f8f1d691000 r--p 00002000 fd:00 67311862                   /usr/lib64/libdl-2.17.so
7f8f1d691000-7f8f1d692000 rw-p 00003000 fd:00 67311862                   /usr/lib64/libdl-2.17.so
7f8f1d692000-7f8f1d855000 r-xp 00000000 fd:00 67311856                   /usr/lib64/libc-2.17.so
7f8f1d855000-7f8f1da55000 ---p 001c3000 fd:00 67311856                   /usr/lib64/libc-2.17.so
7f8f1da55000-7f8f1da59000 r--p 001c3000 fd:00 67311856                   /usr/lib64/libc-2.17.so
7f8f1da59000-7f8f1da5b000 rw-p 001c7000 fd:00 67311856                   /usr/lib64/libc-2.17.so
7f8f1da5b000-7f8f1da60000 rw-p 00000000 00:00 0
7f8f1da60000-7f8f1da75000 r-xp 00000000 fd:00 67991406                   /usr/lib64/libgcc_s-4.8.5-20150702.so.1
7f8f1da75000-7f8f1dc74000 ---p 00015000 fd:00 67991406                   /usr/lib64/libgcc_s-4.8.5-20150702.so.1
7f8f1dc74000-7f8f1dc75000 r--p 00014000 fd:00 67991406                   /usr/lib64/libgcc_s-4.8.5-20150702.so.1
7f8f1dc75000-7f8f1dc76000 rw-p 00015000 fd:00 67991406                   /usr/lib64/libgcc_s-4.8.5-20150702.so.1
7f8f1dc76000-7f8f1dd5f000 r-xp 00000000 fd:00 67312174                   /usr/lib64/libstdc++.so.6.0.19
7f8f1dd5f000-7f8f1df5f000 ---p 000e9000 fd:00 67312174                   /usr/lib64/libstdc++.so.6.0.19
7f8f1df5f000-7f8f1df67000 r--p 000e9000 fd:00 67312174                   /usr/lib64/libstdc++.so.6.0.19
7f8f1df67000-7f8f1df69000 rw-p 000f1000 fd:00 67312174                   /usr/lib64/libstdc++.so.6.0.19
7f8f1df69000-7f8f1df7e000 rw-p 00000000 00:00 0
7f8f1df7e000-7f8f1e07f000 r-xp 00000000 fd:00 67311864                   /usr/lib64/libm-2.17.so
7f8f1e07f000-7f8f1e27e000 ---p 00101000 fd:00 67311864                   /usr/lib64/libm-2.17.so
7f8f1e27e000-7f8f1e27f000 r--p 00100000 fd:00 67311864                   /usr/lib64/libm-2.17.so
7f8f1e27f000-7f8f1e280000 rw-p 00101000 fd:00 67311864                   /usr/lib64/libm-2.17.so
7f8f1e280000-7f8f1e2a2000 r-xp 00000000 fd:00 67311849                   /usr/lib64/ld-2.17.so
7f8f1e482000-7f8f1e488000 rw-p 00000000 00:00 0
7f8f1e49d000-7f8f1e4a1000 rw-p 00000000 00:00 0
7f8f1e4a1000-7f8f1e4a2000 r--p 00021000 fd:00 67311849                   /usr/lib64/ld-2.17.so
7f8f1e4a2000-7f8f1e4a3000 rw-p 00022000 fd:00 67311849                   /usr/lib64/ld-2.17.so
7f8f1e4a3000-7f8f1e4a4000 rw-p 00000000 00:00 0
7ffeaa19c000-7ffeaa1bd000 rw-p 00000000 00:00 0                          [stack]
7ffeaa1c9000-7ffeaa1cb000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

RUN FINISHED; Aborted; core dumped; real time: 2s; user: 0ms; system: 0ms

 

0 Kudos
Highlighted
27 Views

wrong>> delete [] *arr;

delete [] arr;

Jim Dempsey

0 Kudos
Highlighted
27 Views

Also, the row and column index positions differ between Fortran and C++

C++ Array[row][col]

Fortran Array(col, row)

Jim Dempsey

0 Kudos
Highlighted
27 Views

Oh, stupped error! :)

Thank you again, the wrong string was excluded by me:   "delete [] *arr;"

PS. Yes Jim, i know about  "backward" indexing in the arrays passing way.

Malik.

0 Kudos
Highlighted
27 Views

IMHO C/C++ is backwards... due to it not supporting directly multi-dimensional arrays (it syntactically appears to do so through use of arrays of pointers).

Jim Dempsey

0 Kudos