External Interfaces/API |
Memory management within MEX-files is not unlike memory management for regular C or Fortran applications. However, there are special considerations because the MEX-file must exist within the context of a larger application, i.e., MATLAB itself.
Automatic Cleanup of Temporary Arrays
When a MEX-file returns to MATLAB, it gives to MATLAB the results of its computations in the form of the left-hand side arguments - the mxArrays
contained within the plhs[]
list. Any mxArrays
created by the MEX-file that are not in this list are automatically destroyed. In addition, any memory allocated with mxCalloc
, mxMalloc
, or mxRealloc
during the MEX-file's execution is automatically freed.
In general, we recommend that MEX-files destroy their own temporary arrays and free their own dynamically allocated memory. It is more efficient for the MEX-file to perform this cleanup than to rely on the automatic mechanism. However, there are several circumstances in which the MEX-file will not reach its normal return statement. The normal return will not be reached if:
mexErrMsgTxt
occurs.
mexCallMATLAB
occurs and the function being called creates an error. (A MEX-file can trap such errors by using mexSetTrapFlag
, but not all MEX-files would necessarily need to trap errors.)
A careful MEX-file programmer can ensure safe cleanup of all temporary arrays and memory before returning in the first two cases, but not in the last two cases. In the last two cases, the automatic cleanup mechanism is necessary to prevent memory leaks.
Persistent Arrays
You can exempt an array, or a piece of memory, from the MATLAB automatic cleanup by calling mexMakeArrayPersistent
or mexMakeMemoryPersistent
. However, if a MEX-file creates such persistent objects, there is a danger that a memory leak could occur if the MEX-file is cleared before the persistent object is properly destroyed. In order to prevent this from happening, a MEX-file that creates persistent objects should register a function, using mexAtExit
, which will dispose of the objects. (You can use a mexAtExit
function to dispose of other resources as well; for example, you can use mexAtExit
to close an open file.)
For example, here is a simple MEX-file that creates a persistent array and properly disposes of it.
#include "mex.h" static int initialized = 0; static mxArray *persistent_array_ptr = NULL; void cleanup(void) { mexPrintf("MEX-file is terminating, destroying array\n"); mxDestroyArray(persistent_array_ptr); } void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { if (!initialized) { mexPrintf("MEX-file initializing, creating array\n"); /* Create persistent array and register its cleanup. */ persistent_array_ptr = mxCreateDoubleMatrix(1, 1, mxREAL); mexMakeArrayPersistent(persistent_array_ptr); mexAtExit(cleanup); initialized = 1; /* Set the data of the array to some interesting value. */ *mxGetPr(persistent_array_ptr) = 1.0; } else { mexPrintf("MEX-file executing; value of first array element is %g\n", *mxGetPr(persistent_array_ptr)); } }
Hybrid Arrays
Functions such as mxSetPr
, mxSetData
, and mxSetCell
allow the direct placement of memory pieces into an mxArray
. mxDestroyArray
will destroy these pieces along with the entire array. Because of this, it is possible to create an array that cannot be destroyed, i.e., an array on which it is not safe to call mxDestroyArray
. Such an array is called a hybrid array, because it contains both destroyable and nondestroyable components.
For example, it is not legal to call mxFree
(or the ANSI free()
function, for that matter) on automatic variables. Therefore, in the following code fragment, pArray
is a hybrid array.
mxArray *pArray = mxCreateDoubleMatrix(0, 0, mxREAL); double data[10]; mxSetPr(pArray, data); mxSetM(pArray, 1); mxSetN(pArray, 10);
Another example of a hybrid array is a cell array or structure, one of whose children is a read-only array (an array with the const
qualifier, such as one of the inputs to the MEX-file). The array cannot be destroyed because the input to the MEX-file would also be destroyed.
Because hybrid arrays cannot be destroyed, they cannot be cleaned up by the automatic mechanism outlined in Automatic Cleanup of Temporary Arrays. As described in that section, the automatic cleanup mechanism is the only way to destroy temporary arrays in case of a user interrupt. Therefore, temporary hybrid arrays are illegal and may cause your MEX-file to crash.
Although persistent hybrid arrays are viable, we recommend avoiding their use wherever possible.
Advanced Topics | Using LAPACK and BLAS Functions |