External Interfaces/API |
Memory Management Compatibility Issues
MATLAB now implicitly calls mxDestroyArray
, the mxArray
destructor, at the end of a MEX-file's execution on any mxArrays
that are not returned in the left-hand side list (plhs[]
). MATLAB issues a warning when it detects any misconstructed or improperly destructed mxArrays
.
We highly recommend that you fix code in your MEX-files that produces any of the warnings discussed in the following sections. For additional information, see Memory Management in Creating C Language MEX-Files.
Improperly Destroying an mxArray
You cannot use mxFree
to destroy an mxArray
.
Warning: You are attempting to call mxFree on a <class-id> array. The destructor for mxArrays is mxDestroyArray; please call this instead. MATLAB will attempt to fix the problem and continue, but this will result in memory faults in future releases.
In the following example, mxFree
does not destroy the array object. This operation frees the structure header associated with the array, but MATLAB will still operate as if the array object needs to be destroyed. Thus MATLAB will try to destroy the array object, and in the process, attempt to free its structure header again.
Incorrectly Constructing a Cell or Structure mxArray
You cannot call mxSetCell
or mxSetField
variants with prhs[]
as the member array.
Warning: You are attempting to use an array from another scope (most likely an input argument) as a member of a cell array or structure. You need to make a copy of the array first. MATLAB will attempt to fix the problem and continue, but this will result in memory faults in future releases.
In the following example, when the MEX-file returns, MATLAB will destroy the entire cell array. Since this includes the members of the cell, this will implicitly destroy the MEX-file's input arguments. This can cause several strange results, generally having to do with the corruption of the caller's workspace, if the right-hand side argument used is a temporary array (i.e., a literal or the result of an expression).
myfunction('
hello'
) /* myfunction is the name of your MEX-file and your code */ /* contains the following: */ mxArray *temp = mxCreateCellMatrix(1,1); ... mxSetCell(temp, 0, prhs[0]); /* INCORRECT */
Make a copy of the right-hand side argument with mxDuplicateArray
and use that copy as the argument to mxSetCell
(or mxSetField
variants); for example
Creating a Temporary mxArray with Improper Data
You cannot call mxDestroyArray
on an mxArray
whose data was not allocated by an API routine.
Warning: You have attempted to point the data of an array to a block of memory not allocated through the MATLAB API. MATLAB will attempt to fix the problem and continue, but this will result in memory faults in future releases.
If you call mxSetPr
, mxSetPi
, mxSetData
, or mxSetImagData
, specifying memory that was not allocated by mxCalloc
, mxMalloc
, or mxRealloc
as the intended data block (second argument), then when the MEX-file returns, MATLAB will attempt to free the pointer to real data and the pointer to imaginary data (if any). Thus MATLAB will attempt to free memory, in this example, from the program stack. This will cause the above warning when MATLAB attempts to reconcile its consistency checking information.
mxArray *temp = mxCreateDoubleMatrix(0,0,mxREAL); double data[5] = {1,2,3,4,5}; ... mxSetM(temp,1); mxSetN(temp,5); mxSetPr(temp, data); /* INCORRECT */
Rather than use mxSetPr
to set the data pointer, instead create the mxArray
with the right size and use memcpy
to copy the stack data into the buffer returned by mxGetPr
.
mxArray *temp = mxCreateDoubleMatrix(1,5,mxREAL); double data[5] = {1,2,3,4,5}; ... memcpy(mxGetPr(temp), data, 5*sizeof(double)); /* CORRECT */
Potential Memory Leaks
Prior to Version 5.2, if you created an mxArray
using one of the API creation routines and then you overwrote the pointer to the data using mxSetPr
, MATLAB would still free the original memory. This is no longer the case.
pr = mxCalloc(5*5, sizeof(double)); ... <load data into pr> plhs[0] = mxCreateDoubleMatrix(5,5,mxREAL); mxSetPr(plhs[0], pr); /* INCORRECT */
will now leak 5*5*8 bytes of memory, where 8 bytes is the size of a double
.
You can avoid that memory leak by changing the code
pr = mxCalloc(5*5, sizeof(double)); ... <load data into pr> plhs[0] = mxCreateDoubleMatrix(5,5,mxREAL); mxFree(mxGetPr(plhs[0])); mxSetPr(plhs[0], pr);
Note that the first solution is more efficient.
Similar memory leaks can also occur when using mxSetPi
, mxSetData
, mxSetImagData
, mxSetIr
, or mxSetJc
. You can address this issue as shown above to avoid such memory leaks.
MEX-Files Should Destroy Their Own Temporary Arrays
In general, we recommend that MEX-files destroy their own temporary arrays and clean up their own temporary memory. All mxArray
s except those returned in the left-hand side list and those returned by mexGetVariablePtr
may be safely destroyed. This approach is consistent with other MATLAB API applications (i.e., MAT-file applications, engine applications, and MATLAB Compiler generated applications, which do not have any automatic cleanup mechanism.)
Compiler and Platform-Specific Issues | Additional Information |