I wrote a simple mex function which updates already allocated by Matlab array:
mex_test_array.c
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
double *x = mxGetPr(prhs[0]);
x[0] = 3.1416;
}
Test 1:
>> y = zeros(2, 2);
>> mex_test_array(y);
>> y
y =
3.1416 0
0 0
Test 2:
>> y = zeros(2, 2);
>> mex_test_array(y(:, 1));
>> y
y =
0 0
0 0
Why it doesn't work on sub-matrix (Test 2) ? Is it possible to make it work?
Please advise.
Remark:
I understand, that updating input arrays is not how mex files are expected to be writted, and I do know how to return arrays from mex.
The reason I tried this technique is to avoid allocation of the arrays' memory twice.
This shouldn't work, since MATLAB does not want "right-hand-side parameters" to change. See for example the online help:
prhs [is an] Array of pointers to input data. The input data is read-only and
should not be altered by your mexFunction .
That is why your function header
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
says const mxArray *prhs[]
and not mxArray *prhs[]
. If you want to return a value, you are supposed to do that through mxArray *plhs[]
. I think the behaviour for when you change a "right-hand-side parameter" is just undefined and recommend reading the full MEX files guide for further details.
UPDATE
To answer your actual question, I assume that when you hand y
to your function, MATLAB hands you the actual pointer and (falsely) trusts you not to mess with it; when you hand your function y(:,1)
MATLAB makes a copy of that part of the array and hands you a pointer to that copy, which is discarded after your function call.
If you do insist on doing this, at least read Matlab mex in-place editing on Undocumented Matlab, as pointed out in the comments by reve_etrange! Essentially, you must run
mxUnshareArray(const_cast<mxarray *>(prhs[0]), true);
before you modify that array. Otherwise running
>> y = zeros(2, 2);
>> y_backup=y;
>> mex_test_array(y);
will result in
>> y
y =
3.1416 0
0 0
>> y_backup
y =
3.1416 0
0 0
... which makes for some hell-of-a-unmaintainable code!