Memory leak in a c++ mex file. Need to spot the memory leak and resolve it.

3 views (last 30 days)
Hey all. I have been given a (MEX)C++ code to use for an optimization task. I have worked on programming and MEXing FORTRAN codes before, but MEXing C++ is kind new to me especially that I noticed memory leak is a huge issue when I am looping over the MEX file in optimization iterations. It keep eating the memory until MATLAB gives an error and I have to do clear all to free up the memory.
I tried spotting and resolving the spot(s) that memory is leaking but have had no luck. I am by no means an expert in MEXing and memory management so I would like to get some help here from the community experts. Any help that points me toward the right direction will be much appreciated.
Here is my mexFunction:
void mexFunction(int nlhs, const mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
// Function arguments
// t, DT, DP
double t, DT;
// Declare the local structure
structD *DP;
t = *mxGetPr( prhs[0] );
DT = *mxGetPr( prhs[1] );
// Get the root structure that contains the Array and tables
const mxArray *mxDP = prhs[2];
// Get the array structure
const mxArray *mxDPArray = mxGetField( mxDP, 0, (const char *)"DPArray" );
// Convert the array structure to a double array so we can access it directly
double *DPArray = mxGetPr( mxDPArray );
// Now convert the entire structure to the C++ structure.
DP = BuildDP( mxDP );
// Calculate the F values given the inputs
double valuesF = myFunF( t, DT, DP );
// move the DP structure changes back into the F value
DP2F( DP, DPArray, valuesF );
// Return the array with it's changed values
plhs[0] = mxDuplicateArray( mxDPArray );
}
Obviously, there are a couple of other functions called here. I can provide those as well, but I thought it would be better to not make it a long piece of code and stick with the main function.
  4 Comments
James Tursa
James Tursa on 24 Mar 2017
Edited: James Tursa on 24 Mar 2017
Using new and delete is fine, but has the potential risk of a memory leak if the mex routine encounters an error of some sort and returns control back to the caller in between the new and the delete. If it is simple arrays or structs your are allocating, you might consider changing these to using mxMalloc and mxFree (assuming structDamper is just a simple struct of course). That way this memory will be on the garbage collection list and will have no risk of leaking. But if there is no potential for the mex routine to error in between the new and the delete, then I probably wouldn't bother with this.
As for the in-place stuff, here is why I made that remark. mxDPArray is an mxArray that came from a field of prhs[2], an input (i.e., mxGetField points directly at a part of the input variable prhs[2] ... not at a copy). But that last comment in your code says "Return the array with it's changed values", returning a copy of mxDPArray. This would indicate that your code is changing the values inside prhs[2] (presumably the double data of mxDPArray which is a field element of prhs[2] but this code isn't shown so I can't tell for sure). In fact, your code would not make much sense unless this is in fact happening. The danger is that changing an input variable in-place will simultaneously change any variable in the caller workspace that is sharing this variable (shared data copy or reference data copy). You can get away with this in some circumstances, but it can bite you in other circumstances. Now, maybe it is your intention to modify prhs[2] in-place and you are well aware of this. But maybe not, hence my remark.
The standard approach is to duplicate the array at the beginning, and then modify this duplicate. I.e., the outline of the code would look something like the following instead. Note that plhs[0] is created up front, and all data manipulation of the doubles happens on the data of plhs[0], not in-place on the data of one of the input variables.
// Get the root structure that contains the Array and tables
const mxArray *mxDP = prhs[2];
// Get the array structure
const mxArray *mxDPArray = mxGetField( mxDP, 0, (const char *)"DPArray" );
// Create the array to return
plhs[0] = mxDuplicateArray( mxDPArray );
// Convert the array structure to a double array so we can access it directly
double *DPArray = mxGetPr( plhs[0] );
// Now convert the entire structure to the C++ structure.
DP = BuildDP( mxDP );
// Calculate the F values given the inputs
double valuesF = myFunF( t, DT, DP );
// move the DP structure changes back into the F value
DP2F( DP, DPArray, valuesF );
Omid
Omid on 24 Mar 2017
What you say totally makes sense. As I said, I did not write this code. I was responsible to use the compiled version of this c-mex code in an optimization algorithm where I found there is a huge memory leak. Then I asked for the source code to figure out what was causing it. Anyways, what you pointed out, although was not my main question, but I think would have potentially affected the performance of the optimization algorithm I am implementing.
Thanks a lot buddy.

Sign in to comment.

Answers (0)

Categories

Find more on Write C Functions Callable from MATLAB (MEX Files) in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!