Hello,
I am taking @everythingfunctional 's tutorial to the next level by practising all the tutorials from the learn-c website through Fortran’s interoperability and back .
I am trying to pass an array whose length is defined at runtime to C and back to Fortran however I have trouble bringing it back to Fortran after passing it to C. I am doing it this way to exercise C interoperability and learn it.
I get a segfault when trying to send it to C and back to Fortran
My code is as follows
arrays_experiment.c
#include <stdio.h>
extern void average_calculator_fort_int(int * array);
int calculate_average_of_elements_int(int elements,int array[elements])
{
int sum_of_elements;
sum_of_elements=0;
for (int i=0;i<elements;i++)
{
sum_of_elements=sum_of_elements+array[i];
}
printf("The sum is: %d \n",sum_of_elements);
return sum_of_elements/elements;
}
void ask_fortran_too(int elements,int array[elements])
{
average_calculator_fort_int(array);
}
averages_module.f90
module average_calculator
use,intrinsic :: iso_c_binding,only: c_int
implicit none
private
public :: average_calculator_c_int,ask_fortran_too
interface
pure function average_calculator_c_int(length,array) result(average_of_elements)&
bind(C,name="calculate_average_of_elements_int")
import c_int
implicit none
integer(kind=c_int),intent(in),value :: length
integer(kind=c_int),intent(in) :: array(length)
integer(kind=c_int) :: average_of_elements
end function average_calculator_c_int
end interface
interface
subroutine ask_fortran_too(array) bind(C,name="ask_fortran_too")
import c_int
implicit none
integer(kind=c_int),dimension(:),intent(in) :: array
end subroutine ask_fortran_too
end interface
contains
subroutine average_calculator_fort_int(array) bind(C)
integer(kind=c_int),dimension(:),intent(in) :: array
print "(a,1x,i0)", "Fortran says the sum is:",sum(array,1)
print "(a,1x,i0)", "Fortran says the average is:",sum(array,1)/size(array)
end subroutine average_calculator_fort_int
end module average_calculator
main.f90
program main
use,intrinsic :: iso_c_binding,only: c_int
use average_calculator,only: average_calculator_c_int,ask_fortran_too
implicit none
integer(kind=c_int),dimension(:),allocatable :: given_array
integer(kind=c_int) :: given_size
write(unit=*,fmt="(a,1x)",advance="no") "Please enter the number of elements in the array:"
read *, given_size;allocate(given_array(given_size))
write(unit=*,fmt="(a,1x)",advance="no") "Please enter the elements of the array:";read *, given_array
print "(a,1x,i0)", "The average is:",average_calculator_c_int(given_size,given_array)
call ask_fortran_too(given_array)
deallocate(given_array)
end program main
Compiled with
gfortran -O3 arrays_experiment.c averages_module.f90 main.f90 -o average_calculator
run with
./average_calculator
the error I get :
Please enter the number of elements in the array: 3
Please enter the elements of the array: 80 85 90
The sum is: 255
The average is: 85
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
Backtrace for this error:
#0 0x7ff018223a12 in ???
#1 0x7ff018222ba5 in ???
#2 0x7ff017f7fb1f in ???
#3 0x401327 in ???
#4 0x4017af in ???
#5 0x40113c in ???
#6 0x7ff017f6a50f in ???
#7 0x7ff017f6a5c8 in ???
#8 0x401174 in ???
#9 0xffffffffffffffff in ???
Segmentation fault (core dumped)