Why matlab crash when program tries to deallocate the dynamic memory allocated in fortran module

1 次查看(过去 30 天)
Hi, every one! I'm trying to write a little lengthy program. This program is speeded up with mex function in language C. However, in my program, I also have to call some functions written in fortran, and these functions has been well validated since others also use these functions. When I program, I write a interface program in language C and functions written in fortran are called from the interface program.
In this process, some dynamic memory in fortran part has to be allocated at the very begining and deallocated at the end. These dynamic memory are allocated at the first call as follows:
TURBULENCE_mp_INIT_TURBULENCE(NameList, buf, &nlev, buflen);
The above sentence is run to call the following function in fortran:
subroutine init_turbulence(namlst,fn,nlev)
IMPLICIT NONE
integer, intent(in) :: namlst
character(len=*), intent(in) :: fn
integer, intent(in) :: nlev
integer :: rc
REALTYPE :: L_min
!
namelist /turbulence/ turb_method,tke_method, &
len_scale_method,stab_method
namelist /bc/ k_ubc,k_lbc,kb_ubc,kb_lbc, &
psi_ubc,psi_lbc, &
ubc_type,lbc_type
namelist /turb_param/ cm0_fix,Prandtl0_fix,cw, &
compute_kappa,kappa, &
compute_c3,ri_st,length_lim,galp, &
const_num,const_nuh,k_min,eps_min, &
kb_min,epsb_min
namelist /generic/ compute_param,gen_m,gen_n,gen_p, &
cpsi1,cpsi2,cpsi3minus,cpsi3plus, &
sig_kpsi,sig_psi, &
gen_d,gen_alpha,gen_l
namelist /keps/ ce1,ce2,ce3minus,ce3plus,sig_k, &
sig_e,sig_peps
namelist /my/ e1,e2,e3,sq,sl,my_length,new_constr
namelist /scnd/ scnd_method,kb_method,epsb_method, &
scnd_coeff, &
cc1,cc2,cc3,cc4,cc5,cc6, &
ct1,ct2,ct3,ct4,ct5,ctt
namelist /iw/ iw_model,alpha,klimiw,rich_cr, &
numiw,nuhiw,numshear
!
! allocate memory
LEVEL2 'allocation memory..'
allocate(tke(0:nlev),stat=rc)
if (rc /= 0) stop 'init_turbulence: Error allocating (tke)'
tke = k_min
allocate(tkeo(0:nlev),stat=rc)
if (rc /= 0) stop 'init_turbulence: Error allocating (tkeo)'
tkeo = k_min
allocate(eps(0:nlev),stat=rc)
if (rc /= 0) stop 'init_turbulence: Error allocating (eps)'
eps = eps_min
allocate(L(0:nlev),stat=rc)
if (rc /= 0) stop 'init_turbulence: Error allocating (L)'
L = _ZERO_
LEVEL2 'allocation memory..'
allocate(kb(0:nlev),stat=rc)
if (rc /= 0) stop 'init_turbulence: Error allocating (kb)'
kb = kb_min
LEVEL2 'allocation memory..'
allocate(epsb(0:nlev),stat=rc)
if (rc /= 0) stop 'init_turbulence: Error allocating (epsb)'
epsb = epsb_min
allocate(P(0:nlev),stat=rc)
if (rc /= 0) stop 'init_turbulence: Error allocating (P)'
P = _ZERO_
allocate(B(0:nlev),stat=rc)
if (rc /= 0) stop 'init_turbulence: Error allocating (B)'
B = _ZERO_
allocate(Pb(0:nlev),stat=rc)
if (rc /= 0) stop 'init_turbulence: Error allocating (Pb)'
Pb = _ZERO_
allocate(num(0:nlev),stat=rc)
if (rc /= 0) stop 'init_turbulence: Error allocating (num)'
num = 1.0D-6
allocate(nuh(0:nlev),stat=rc)
if (rc /= 0) stop 'init_turbulence: Error allocating (nuh)'
nuh = 1.0D-6
allocate(nus(0:nlev),stat=rc)
if (rc /= 0) stop 'init_turbulence: Error allocating (nus)'
nus = 1.0D-6
allocate(gamu(0:nlev),stat=rc)
if (rc /= 0) stop 'init_turbulence: Error allocating (gamu)'
gamu = _ZERO_
allocate(gamv(0:nlev),stat=rc)
if (rc /= 0) stop 'init_turbulence: Error allocating (gamv)'
gamv = _ZERO_
allocate(gamb(0:nlev),stat=rc)
if (rc /= 0) stop 'init_turbulence: Error allocating (gamb)'
gamb = _ZERO_
allocate(gamh(0:nlev),stat=rc)
if (rc /= 0) stop 'init_turbulence: Error allocating (gamh)'
gamh = _ZERO_
allocate(gams(0:nlev),stat=rc)
if (rc /= 0) stop 'init_turbulence: Error allocating (gams)'
gams = _ZERO_
allocate(cmue1(0:nlev),stat=rc)
if (rc /= 0) stop 'init_turbulence: Error allocating (cmue1)'
cmue1 = _ZERO_
allocate(cmue2(0:nlev),stat=rc)
if (rc /= 0) stop 'init_turbulence: Error allocating (cmue2)'
cmue2 = _ZERO_
allocate(gam(0:nlev),stat=rc)
if (rc /= 0) stop 'init_turbulence: Error allocating (gam)'
gam = _ZERO_
allocate(an(0:nlev),stat=rc)
if (rc /= 0) stop 'init_turbulence: Error allocating (an)'
an = _ZERO_
allocate(as(0:nlev),stat=rc)
if (rc /= 0) stop 'init_turbulence: Error allocating (as)'
as = _ZERO_
allocate(at(0:nlev),stat=rc)
if (rc /= 0) stop 'init_turbulence: Error allocating (at)'
at = _ZERO_
allocate(r(0:nlev),stat=rc)
if (rc /= 0) stop 'init_turbulence: Error allocating (r)'
r = _ZERO_
allocate(Rig(0:nlev),stat=rc)
if (rc /= 0) stop 'init_turbulence: Error allocating (Rig)'
Rig = _ZERO_
allocate(xRf(0:nlev),stat=rc)
if (rc /= 0) stop 'init_turbulence: Error allocating (xRf)'
xRf = _ZERO_
allocate(uu(0:nlev),stat=rc)
if (rc /= 0) stop 'init_turbulence: Error allocating (uu)'
uu = _ZERO_
allocate(vv(0:nlev),stat=rc)
if (rc /= 0) stop 'init_turbulence: Error allocating (vv)'
vv = _ZERO_
allocate(ww(0:nlev),stat=rc)
if (rc /= 0) stop 'init_turbulence: Error allocating (ww)'
ww = _ZERO_
# ifdef EXTRA_OUTPUT
allocate(turb1(0:nlev),stat=rc)
if (rc /= 0) stop 'init_turbulence: Error allocating (turb1)'
turb1 = _ZERO_
allocate(turb2(0:nlev),stat=rc)
if (rc /= 0) stop 'init_turbulence: Error allocating (turb2)'
turb2 = _ZERO_
allocate(turb3(0:nlev),stat=rc)
if (rc /= 0) stop 'init_turbulence: Error allocating (turb3)'
turb3 = _ZERO_
allocate(turb4(0:nlev),stat=rc)
if (rc /= 0) stop 'init_turbulence: Error allocating (turb4)'
turb4 = _ZERO_
allocate(turb5(0:nlev),stat=rc)
if (rc /= 0) stop 'init_turbulence: Error allocating (turb5)'
turb5 = _ZERO_
return
end subroutine init_turbulence
This part runs smoothly, and no errors occured. After finish all the work, the memory allocated above is deallocated with the following function call from the interface program:
TURBULENCE_mp_CLEAN_TURBULENCE();
The above sentence is used to call the follwing function in fortran:
subroutine clean_turbulence()
LEVEL2 'de-allocating turbulence memory ...'
if (allocated(tke)) deallocate(tke)
if (allocated(tkeo)) deallocate(tkeo)
if (allocated(eps)) deallocate(eps)
if (allocated(L)) deallocate(L)
if (allocated(kb)) deallocate(kb)
if (allocated(epsb)) deallocate(epsb)
if (allocated(P)) deallocate(P)
if (allocated(B)) deallocate(B)
if (allocated(Pb)) deallocate(Pb)
if (allocated(num)) deallocate(num)
if (allocated(nuh)) deallocate(nuh)
if (allocated(nus)) deallocate(nus)
if (allocated(gamu)) deallocate(gamu)
if (allocated(gamv)) deallocate(gamv)
if (allocated(gamb)) deallocate(gamb)
if (allocated(gamh)) deallocate(gamh)
if (allocated(gams)) deallocate(gams)
if (allocated(cmue1)) deallocate(cmue1)
if (allocated(cmue2)) deallocate(cmue2)
if (allocated(gam)) deallocate(gam)
if (allocated(an)) deallocate(an)
if (allocated(as)) deallocate(as)
if (allocated(at)) deallocate(at)
if (allocated(r)) deallocate(r)
if (allocated(Rig)) deallocate(Rig)
if (allocated(xRf)) deallocate(xRf)
if (allocated(uu)) deallocate(uu)
if (allocated(vv)) deallocate(vv)
if (allocated(ww)) deallocate(ww)
# ifdef EXTRA_OUTPUT
if (allocated(turb1)) deallocate(turb1)
if (allocated(turb2)) deallocate(turb2)
if (allocated(turb3)) deallocate(turb3)
if (allocated(turb4)) deallocate(turb4)
if (allocated(turb5)) deallocate(turb5)
# endif
LEVEL2 'done.'
return
end subroutine clean_turbulence
However, program crashed in this function call. I tried to debug this part and found it crashed when it call the first sentence:
if (allocated(tke)) deallocate(tke)
I wonder why the program crashes here.
Thanks in advace
  2 个评论
James Tursa
James Tursa 2021-1-7
编辑:James Tursa 2021-1-7
Some questions:
In your C interface code, is NameList a pointer to an integer type? How can you be sure that it is the same integer size that Fortran is expecting? How is it declared? How do you know what size the integer is on the Fortran side?
In your C interface code, it appears you pass the character string length buflen (the length of buf) as the last argument. Are you sure your Fortran compiler puts this at the end of the argument list and not next to buf? And are you sure you are using the correct integer size for buflen that your Fortran compiler uses for this (32-bit or 64-bit integer)?
In your Fortran code, I don't see your allocatable variables (tke, tkeo, etc.) declared anywhere. Are they module variables? Are your subroutines part of a module? Can you clarify where these variables live and how your code is structured?
When you write "After finish all the work", does this mean you deallocate the Fortran variables inside the code before returning to the C interface code? Or does that mean you return to the C interface code, and then on a subsequent call try to deallocate the Fortran variables that were allocated on a previous call? Do you return all the way to MATLAB inbetween the allocation and deallocation calls?
Is the Fortran code a regular compiled object file that is linked in with the C interface object file via the mex command?
Rylan
Rylan 2021-1-8
Thanks for your questions.
According to your questions, I have found the exact reason. I made a careless mistake. During the computation, the address the pointer scheduled to point to is frequently changed.
Sorry for this careless mistake and thanks for your time!

请先登录,再进行评论。

回答(0 个)

类别

Help CenterFile Exchange 中查找有关 Fortran with MATLAB 的更多信息

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by