Re: calling a function once works, calling it twice fails
- From: "e p chandler" <epc8@xxxxxxxx>
- Date: Sat, 29 Nov 2008 20:07:21 -0500
"Louis Krupp" <lkrupp@xxxxxxxxxxxxxxxxxxxxxxx> wrote in message news:JYSdnUySyfTRA6zUnZ2dnUVZ_rjinZ2d@xxxxxxxxxxxxxxxx
Isomorphismus wrote:Hi!
I have linked a C++-program with a fortran routine, where the fortran
routine should read data of a file. The problem now is, that the first
time I call the fortran routine, everything works fine and I get the
data I need. Calling it twice, I get a segmentation fault. Here is the
code:
the calling c++ program:
#include <iostream>
using namespace std;
#ifdef __GNUC__
#define STDCALL
#endif
extern "C" { void STDCALL read_dimensions_(char*,
char*,int*,int*,int,int);
void STDCALL read_aso_file_
(char*,char*,int*,double*,int,int);
}
char path[30] = "/home/happenhofer/readAso/";
char aname[30] = "c2d-T320-cool_dg.00000.aso";
char aname1[30] = "c2d-T320-cool_t.00000.aso";
int dims;
int xdims,ydims;
int main()
{
read_dimensions_ (path,aname,&xdims,&ydims,strlen(path),strlen
(aname));
cout << xdims << ", " << ydims << endl;
double* data = new double[xdims*ydims];
if(!data) cout << "could not allocate memory for data" << endl;
dims = xdims*ydims;
read_aso_file_(path,aname,&dims,data,strlen(path),strlen(aname));
cout << "bin zurück, aber vor ausgabeschleife" << endl;
for(int i=0; i<xdims*ydims; i++) cout << data[i] << endl;
cout << "lese 2. Datei" << endl;
read_aso_file_(path,aname1,&dims,data,strlen(path),strlen
(aname1));
for(int j=0; j < xdims*ydims; j++) cout << data[j] << endl;
return 0;
}
and the fortran_file:
subroutine READ_DIMENSIONS(path, aname, xdims, ydims)
implicit none
integer :: aso_unit=10, aso_unit1 = 9, plt_unit=11
integer :: nx_aso_a,nx_aso_b,ny_aso_a,ny_aso_b,nz_aso_a,nz_aso_b
integer ::
x_max_aso,y_max_aso,z_max_aso,x_min_aso,y_min_aso,z_min_aso
integer,parameter:: maxvars_param_aso = 29
integer, parameter :: aso_filenames_length = 80
character(len=aso_filenames_length) :: aso_filename_string
integer,dimension(maxvars_param_aso) :: aso_further_spec = 1 ,
aso_typ = 1
real(kind(0.0e0)),allocatable :: in_arr(:),px_aso(:),py_aso(:),pz_aso
(:)
character(100) :: aso_name,plt_name
character(100) :: mod_name
character(5) :: mod_no_char,var_name
integer :: aso_no,len_aso_name,len_mod_name,len_var_name,mod_no,
len_aname
real(kind(0.0e0)),dimension(:,:,:,:),pointer :: var
real(kind(0.0e0)) ::
tot_time,n_df_od1_g,n_df_od2_g,n_df_od3_g,n_df_od4_g
integer :: i,j,k,i_var,ver,n_df_od1,n_df_od2,n_df_od3,n_df_od4
logical :: l_1d,l_2d,l_3d
integer :: dim,n_var=20
logical :: l_aso_exist,l_df
integer :: mod_no1,mod_no2,mod_stp
integer :: xdims, ydims
character(*)::path,aname
integer :: code_spec
logical,save :: l_alloc=.true.
mod_name=path
ver = 1
len_mod_name=len(trim(mod_name))
len_aname = len(trim(aname))
aso_name = mod_name(1:len_mod_name) // aname(1:len_aname)
inquire(file=trim(aso_name),exist=l_aso_exist)
if (l_aso_exist) then
open(unit=aso_unit,file=aso_name,form='unformatted')
else
return
endif
read(aso_unit) aso_typ(1)
read(aso_unit) aso_filename_string
read(aso_unit) tot_time
read(aso_unit)aso_further_spec(1)
read(aso_unit)
x_min_aso,x_max_aso,y_min_aso,y_max_aso,z_min_aso,z_max_aso
xdims = x_max_aso
ydims = y_max_aso
close(aso_unit)
end subroutine READ_DIMENSIONS
subroutine READ_ASO_FILE(path, aname, dims, data1)
implicit none
integer :: aso_unit=10, aso_unit1 = 9, plt_unit=11
integer :: nx_aso_a,nx_aso_b,ny_aso_a,ny_aso_b,nz_aso_a,nz_aso_b
integer ::
x_max_aso,y_max_aso,z_max_aso,x_min_aso,y_min_aso,z_min_aso
integer,parameter:: maxvars_param_aso = 29
integer, parameter :: aso_filenames_length = 80
character(len=aso_filenames_length) :: aso_filename_string
integer,dimension(maxvars_param_aso) :: aso_further_spec = 1 ,
aso_typ = 1
real(kind(0.0e0)),allocatable :: in_arr(:),px_aso(:),py_aso(:),pz_aso
(:)
character(100) :: aso_name,plt_name
character(100) :: mod_name
character(5) :: mod_no_char,var_name
integer :: aso_no,len_aso_name,len_mod_name,len_var_name,mod_no,
len_aname
real(kind(0.0e0)),dimension(:,:,:,:),pointer :: var
real(kind(0.0e0)) ::
tot_time,n_df_od1_g,n_df_od2_g,n_df_od3_g,n_df_od4_g
integer :: i,j,k,i_var,ver,n_df_od1,n_df_od2,n_df_od3,n_df_od4
logical :: l_1d,l_2d,l_3d
integer :: dim,n_var=20
logical :: l_aso_exist,l_df
integer :: mod_no1,mod_no2,mod_stp
integer(kind(0)) :: dims
character(*)::path,aname
real, dimension(dims):: data2
real(kind(0.0d0)),dimension(dims)::data1
integer :: code_spec, counter=0
logical,save :: l_alloc=.true.
mod_name=path
ver = 1
write(*,*) "dims",dims
len_mod_name=len(trim(mod_name))
len_aname = len(trim(aname))
aso_name = mod_name(1:len_mod_name) // aname(1:len_aname)
inquire(file=trim(aso_name),exist=l_aso_exist)
if (l_aso_exist) then
open(unit=aso_unit1,file=aso_name,form='unformatted')
else
return
endif
write(*,*) 'file opened in read_aso_file'
read(aso_unit1) aso_typ(1)
read(aso_unit1) aso_filename_string
read(aso_unit1) tot_time
read(aso_unit1)aso_further_spec(1)
read(aso_unit1)
x_min_aso,x_max_aso,y_min_aso,y_max_aso,z_min_aso,z_max_aso
if (l_alloc) then
call ALLOC ()
l_alloc=.false.
endif
do j = y_min_aso,y_max_aso
read(aso_unit1) data2((counter*x_max_aso + 1):((counter+1)
*x_max_aso))
counter = counter + 1
end do
do j=1,dims
data1(j) = data2(j)
enddo
close(aso_unit1)
continue
contains
subroutine ALLOC ()
implicit none
if (y_max_aso .eq. 1 .and. z_max_aso .eq. 1) then
dim=1
l_3d=.false.; l_2d=.false.; l_1d=.true.
elseif (z_max_aso .eq. 1) then
dim=2
l_3d=.false.; l_2d=.true.; l_1d=.false.
else
dim=3
l_3d=.true.; l_2d=.false.; l_1d=.false.
endif
!allocate arrays
allocate(in_arr(x_min_aso:x_max_aso)); in_arr = 0.0d0
!N allocate(px_aso(x_min_aso:x_max_aso)); px_aso = 0.0d0
!N allocate(py_aso(y_min_aso:y_max_aso)); py_aso = 0.0d0
!N allocate(pz_aso(z_min_aso:z_max_aso)); pz_aso = 0.0d0
if (ver .eq. 1) allocate(var
(1:1,x_min_aso:x_max_aso,y_min_aso:y_max_aso,z_min_aso:z_max_aso));
var = 0.0d0
if (ver .eq. 2) allocate(var
(1:20,x_min_aso:x_max_aso,y_min_aso:y_max_aso,z_min_aso:z_max_aso));
var = 0.0d0
end subroutine ALLOC
subroutine DEALLOC ()
implicit none
deallocate(in_arr)
!N deallocate(px_aso)
!N deallocate(py_aso)
!N deallocate(pz_aso)
!N deallocate(var)
end subroutine DEALLOC
end subroutine READ_ASO_FILE
as I said, the call to read_dimensions and the first call to
read_aso_file works fine. In the second call I get a segmentation
fault at the end, i.e the file is read correctly, in data2 are the
correct values stored, but assigning them to data1 fails. It seems
that at the second call the array data1 is corrupt, but why did it
work the first time, then?
thx for any help,
Natalie Happenhofer /Isomorphismus
Does your Fortran compiler have an option to check array subscripts? I would turn that on and see what happens.
Louis
Well Louis is better at sight reading Fortran code than I am. My post was somewhat off base. :-(. But there is so much *stuff* in your code, that it is difficult to find what *might* be at fault.
If you are using g95 or gfortran, then you should try -fbounds-check as a compiler option to detect array access out of bounds.
Here is where I think the fault is:
In READ_ASO_FILE() you have
integer :: code_spec, counter=0
I suspect that this is what is going wrong.
On the first call to this routine, counter starts at 0. On the second call to this routine, counter starts at its LAST PREVIOUS VALUE. Initialization implies "save" so counter retains its state between calls. It is NOT set to ZERO each time it is called. If you want it re-set to zero on each entry, then you have to assign a value of zero to it each time.
See a recent thread in this newsgroup about "automatic" for a discussion.
Your code to create the fully qualified path name for the file is awkward for Fortran. Why not
actual_file_name = trim(path) // trim (aname) if you actually need the trim() at all.
Next, you have no provisions for an error exit from read_dimensions(). What are xdims and ydims if the routine exits early??? Likewise there is no provision for an early exit from read_aso_file().
Last, some points of style. Try writing a routine, and posting such a routine, with the minimum needed to get it to run. The extraneous declarations and the internal routines ALLOC() and DEALLOC() are a distraction.
Keep removing until removing something else makes the program fail to compile!
Organize variable declarations in some fashion. I tend to list those for arguments to the routine first.
There should be a more "Fortran like" way of reading data2. Maybe make data1 a two dimensional array. Read it row-by-row. Then your returned value array is the transpose of data2.
If you wrote the Fortran routines, then you have "C" on the brain. Fortran lets you handle character variables and arrays at a higher level. I suggest you learn and use its facilities to your advantage.
-- e
.
- References:
- calling a function once works, calling it twice fails
- From: Isomorphismus
- calling a function once works, calling it twice fails
- Prev by Date: Re: Final Procedure
- Next by Date: Re: Final Procedure
- Previous by thread: Re: calling a function once works, calling it twice fails
- Next by thread: Final Procedure
- Index(es):
Relevant Pages
|