Memory Leak Likely - Fortran Mex file

2 views (last 30 days)
Mark Adams
Mark Adams on 30 Dec 2021
Commented: James Tursa on 3 Jan 2022
I have Matlab code that looks like the following (just part of vey large program) : I have Visual Studio with Windows 10 on my PC
With an explanation afterwards. I am an inexperienced Mex programmer.
Any help would be much appreciated. Thanks and happy holidays!
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
function [Solnd,resid,success] = solbvp(glb,Ts,Tt,flg,flg1,alnd,prgin,prgeq,prgbc,lab)
global TTnd Sol0 aa thtype Vemaxnd Veminnd beta nsf
N = length(TTnd);
success = 1;
[Solnd, resid] = deal(NaN);
[nstates,dummy] = size(Sol0);
lastwarn('');
warning('off');
if flg1 == 1
try
[Solnd,resid,success]=bvpsolver2(TTnd,Sol0);
catch ME
success = 0;
fprintf('\n %s. Singularity at T_s = %5.1f, T_t = %5.1f',lab,Ts,Tt)
end
end
if flg1 == 2
try
for i=1:4
aa_copy(i)=aa(1,i);
end
aa_copy(5)=0.0;
aa_copy(6)=0.0;
aa_copy(7)=0.0;
[Solnd,resid,success]=bvpsolver3(TTnd,Sol0,thtype,aa_copy.',Vemaxnd,Veminnd,nsf);
catch ME
success = 0;
fprintf('\n %s. Bvpsolver 3 error at T_s = %5.1f, T_t = %5.1f',lab,Ts,Tt)
end
end
if flg1 == 3
try
for i=1:4
aa_copy(i)=aa(1,i)
end
aa_copy(5)=0.0;
aa_copy(6)=0.0;
aa_copy(7)=0.0;
[Solnd,resid,success]=bvpsolver3(TTnd,Sol0,thtype,aa_copy.',Vemaxnd,Veminnd,nsf);
catch ME
success = 0;
fprintf('\n %s. Bvpsolver 3 error at T_s = %5.1f, T_t = %5.1f',lab,Ts,Tt)
end
end
% ....
%.....(more code) here
end % solbvp
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Most of the function call 'solbvp' is used to compute the solution to a boundary value ordinary differential equation system.
We have replaced the call to the MATLAB built in function BVP5C with a call to two MEX files - bvpsolver2 and bvpsolver3.
Both are intended to solve different sets of BVPs. The code works for first time calls to the mex files (flg1==1 and flg1==2) but MATLAB automatically shuts down for (flg1==3) The second call to bvpsolver3. I think the mex code is okay for bvpsolver2 because I have run it in an extensive loop before. So I only include the mex code for bvpsolver3 below. The code which is for debugging (printing to MATLAB screen) is not in bold. Very important code probably related to the memory leak is in bold.
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Code for Mex file BVPSOLVER3
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#include "fintrf.h"
C======================================================================
#if 0
C
C bvpsolver3.F
C .F file needs to be preprocessed to generate .for equivalent
C
#endif
C
C======================================================================
C Gateway routine
subroutine mexFunction(nlhs, plhs, nrhs, prhs)
C Declarations
implicit none
C mexFunction arguments:
mwPointer plhs(*), prhs(*)
integer nlhs, nrhs
integer mxIsNumeric
C Function declarations:
mwPointer mxGetPr
mwPointer mxCreateNumericArray
integer*4 mxClassIDFromClassName
integer*4 classid
integer*4 complexflag
mwSize ndim
mwSize dims(2)
mwPointer mxCreateDoubleScalar
mwPointer mxCreateDoubleMatrix
mwPointer mxGetM, mxGetN
C Pointers to input/output mxArrays:
mwPointer T_ptr,YI_ptr, YF_ptr, E_ptr, I_ptr
mwPointer thtype_ptr,aa_ptr,vemax_ptr,vemin_ptr,nsf_ptr
C Array information:
mwPointer mrows, ncols,mrows_aa
mwSize size
mwSize rowsize,aa_size
C Arguments for computational routine:
real*8 YI_in(3200), T_in(200), E_out, YF_out(3200)
integer*4 I_out,m_in,n_in
real*8 aa_in(7),vemax_in,vemin_in,thtype_in_real,nsf_in_real
integer*4 thtype_in,nsf_in
c--------------------------------------------------------------------------
character (len=50) :: c
character (len=50) :: txt
C-----------------------------------------------------------------------
C Specify alert to be printed
write(txt,'(A)') 'Number of inputs (mexPrintf): '
C Convert nrhs to char
write(c,'(i1)') nrhs
C Call the API
call mexPrintf(txt)
call mexPrintf(c)
C Check for proper number of arguments.
if(nrhs.eq.7)then
call mexprintf('hello6crud')
endif
if(nlhs.eq.3)then
call mexprintf('hello9crud')
endif
mrows_aa=mxGetM(prhs(4))
if(mrows_aa.eq.4)then
call mexprintf('hello15')
endif
mrows = mxGetM(prhs(2))
ncols = mxGetN(prhs(2))
size = mrows*ncols
rowsize=mrows*1
aa_size=mrows_aa*1
if(size.eq.3200)then
call mexprintf('hello33')
endif
if(mrows.eq.16)then
call mexprintf('hello36')
endif
T_ptr = mxGetPr(prhs(1))
YI_ptr = mxGetPr(prhs(2))
thtype_ptr = mxGetPr(prhs(3))
aa_ptr = mxGetPr(prhs(4))
vemax_ptr = mxGetPr(prhs(5))
vemin_ptr = mxGetPr(prhs(6))
nsf_ptr = mxGetPr(prhs(7))
call mxCopyPtrToReal8(T_ptr,T_in,ncols)
call mxCopyPtrToReal8(YI_ptr,YI_in,size)
call mxCopyPtrToReal8(aa_ptr,aa_in,7)
C Specify alert to be printed
write(txt,'(A)') 'aa_size (mexPrintf): '
C Convert nrhs to char
write(c,'(i1)')aa_size
C Call the API
call mexPrintf(txt)
call mexPrintf(c)
C Specify alert to be printed
write(txt,'(A)') 'aa_in(1) (mexPrintf): '
C Convert nrhs to char
write(c,'(f10.4)')aa_in(1)
C Call the API
call mexPrintf(txt)
call mexPrintf(c)
call mxCopyPtrToReal8(vemax_ptr,vemax_in,1)
call mxCopyPtrToReal8(vemin_ptr,vemin_in,1)
call mxCopyPtrToReal8(thtype_ptr,thtype_in_real,1)
thtype_in=int(thtype_in_real)
call mxCopyPtrToReal8(nsf_ptr,nsf_in_real,1)
nsf_in=int(nsf_in_real)
plhs(1) = mxCreateDoubleMatrix(mrows,ncols,0)
plhs(2) = mxCreateDoubleScalar(1)
classid = mxClassIDFromClassName("int32")
complexflag = 0
ndim = 2
dims(1) = 1
dims(2) = 1
plhs(3) = mxCreateNumericArray(ndim, dims,classid,complexflag)
YF_ptr = mxGetPr(plhs(1))
E_ptr = mxGetPr(plhs(2))
I_ptr = mxGetPr(plhs(3))
C Specify alert to be printed
write(txt,'(A)') 'thtype_in (mexPrintf): '
C Convert nrhs to char
write(c,'(i1)')thtype_in
C Call the API
call mexPrintf(txt)
call mexPrintf(c)
C Specify alert to be printed
write(txt,'(A)') 'nsf_in (mexPrintf): '
C Convert nrhs to char
write(c,'(i1)')nsf_in
C Call the API
call mexPrintf(txt)
call mexPrintf(c)
C Specify alert to be printed
write(txt,'(A)') 'vemax_in (mexPrintf): '
C Convert nrhs to char
write(c,'(f10.4)')vemax_in
C Call the API
call mexPrintf(txt)
call mexPrintf(c)
C Specify alert to be printed
write(txt,'(A)') 'vemin_in (mexPrintf): '
C Convert nrhs to char
write(c,'(f10.4)')vemin_in
C Call the API
call mexPrintf(txt)
call mexPrintf(c)
call bvpsolver3(YF_out,E_out,I_out,T_in,YI_in,
+ thtype_in,aa_in,vemax_in,vemin_in,nsf_in)
call mxCopyReal8ToPtr(YF_out,YF_ptr,size)
call mxCopyReal8ToPtr(E_out,E_ptr,1)
call mxCopyInteger4ToPtr(I_out,I_ptr,1)
return
end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1 Comment
James Tursa
James Tursa on 3 Jan 2022
Why do you think there is a memory leak? The only dynamic memory allocation I see is from API functions, which should not produce a memory leak because they are garbage collected. MATLAB shutting down is typically the sign of code accessing invalid memory, not a memory leak. You need to examine your data sizes and look for accessing beyond the end of an array, etc.

Sign in to comment.

Answers (0)

Community Treasure Hunt

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

Start Hunting!