MATLAB: Return (large) unchange mxArray from MEX

arraycppMATLABmexreturn

Hi all ..
With a large array out to CPP / MEX, under certain conditions there will be no manipulation of the original data. Can someone please provide an example of how to properly return this original array in the most efficient manner?
Essentially plhs[0] = prhs[0] logically.
Many thanks, Mark

Best Answer

plhs[0] = prhs[0] is perfectly OK in mex programming. MATLAB always (EDIT: NOT TRUE ... SEE BELOW) makes shared data copies of the plhs[ ] mxArrays and actually returns the shared data copies. To see this is true you can do this:
1) Compile this code (call it plhs_eq_prhs.c):
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
if( nrhs ) {
plhs[0] = prhs[0];
mexPrintf("The mxArray structure address of the input is %p\n",prhs[0]);
}
}
2) Run the following commands at the MATLAB prompt:
>> format debug
>> a = 1:3
a =
Structure address = 46cdda0
m = 1
n = 3
pr = 16c3a440
pi = 0
1 2 3
>> b = plhs_eq_prhs(a)
The mxArray structure address of the input is 046CDDA0
b =
Structure address = 495aea0
m = 1
n = 3
pr = 16c3a440
pi = 0
1 2 3
You can see that the mxArray structure address of the variable b is different from the mxArray structure address of the input variable a, but the data pointers pr are the same. So MATLAB has returned a shared data copy back to the workspace.
You can get almost the same result by using the following:
mxArray *mxCreateSharedDataCopy(mxArray *); // supply the prototype
:
plhs[0] = mxCreateSharedDataCopy(prhs[0]);
However, in this case there will be an extra temporary shared data copy of prhs[0] created that will be destroyed when the mex routine returns to the caller, so it is slightly less efficient that doing plhs[0] = prhs[0] directly.
The general behavior of the MATLAB API functions (the documented ones) is:
- All of the mxCreateEtc type of functions create temporary mxArrays that are put on the Variable Array List (my terminology).
- When the mex routine returns control to the caller, MATLAB makes shared data copies of the plhs[ ] variables and returns those, then everything on the Variable Array List is destroyed.
- Using mexMakeArrayPersistent removes a mxArray variable from the Variable Array List. Once a variable is removed from this list, I am unaware of any function (documented or undocumented) that will get it back on this list. So it is up to you, the programmer, to destroy it at some point in your code or you will have a permanent memory leak that can only be recovered by quitting and restarting MATLAB.
- There is a companion function mexMakeMemoryPersistent for memory allocations made with mxMalloc and friends, but in this case there is an undocumented function you can use to get it back on the garbage collection list if you want.
- There are undocumented API functions that create mxArray variables. Some of them create temporary mxArray variables that are on the Variable Array List (i.e., scheduled for garbage collection), but others create normal variables that are not on the Variable Array List. So you need to be careful when using them to avoid permanent memory leaks. mxCreateSharedDataCopy is an example of one of these undocumented API functions ... it happens to create a temporary mxArray that is on the Variable Array List (scheduled for garbage collection).