Assigning mxUint16 variable to plhs[0]

3 views (last 30 days)
I am stuck trying to assign uint16 variable to my MEX output. I boiled it down to the following code, which compiles just fine but still crashes Matlab:
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
mxUint16 variable;
variable = (mxUint16)127;
mwSize dims[2];
dims[0] = 1;
dims[1] = 1;
plhs[0] = mxCreateNumericArray(2, dims, mxUINT16_CLASS, mxREAL);
mxSetUint16s(plhs[0], &variable);
}
Any ideas what could be wrong?

Accepted Answer

James Tursa
James Tursa on 3 Dec 2021
Edited: James Tursa on 3 Dec 2021
You cannot attach native C/C++ memory to an mxArray. The MATLAB API "mxSetEtc" functions check to see that the memory addresses passed in are from the MATLAB Memory Manager, and if not then they crash with an assertion fault. Even if it didn't crash right away, note that the memory address you are passing in comes from a local stack variable (i.e., &variable points to stack memory), and this memory address becomes invalid as soon as the mex function returns to the caller. To do what you are trying to do, you need to get the memory from the MATLAB Memory Manager. E.g.,
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
mxUint16 *variableptr; // a local pointer to mxUint16
variableptr = (mxUint16 *) mxMalloc(sizeof(*variableptr)); // alloc MATLAB memory behind the pointer
*variableptr = (mxUint16)127; // assign value to memory behind pointer
mwSize dims[2];
dims[0] = 1;
dims[1] = 1;
plhs[0] = mxCreateNumericArray(2, dims, mxUINT16_CLASS, mxREAL);
mxFree(mxGetUint16s(plhs[0])); // free the plhs[0] data memory that is currently there
mxSetUint16s(plhs[0], variableptr); // attach the MATLAB alloc memory pointer
}
In the above example, the memory to store the data value 127 is allocated by the MATLAB Memory Manager, so it is safe to attach this directly to an mxArray. The mxSetUint16s( ) function call will remove this data memory from the garbage collection list, so it will in effect become persistent with this call and remain valid when the mex function returns to the caller. The mxFree( ) function call is necessary to avoid a memory leak.
Another way to do this is to manipulate the plhs[0] data pointer directly. E.g.,
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
mwSize dims[2];
dims[0] = 1;
dims[1] = 1;
plhs[0] = mxCreateNumericArray(2, dims, mxUINT16_CLASS, mxREAL);
*mxGetUint16s(plhs[0]) = (mxUint16)127; // assign value to memory behind data pointer
}
Here we are simply getting the current data pointer and then stuffing that location with our 127 value.
  1 Comment
Dries Neirynck
Dries Neirynck on 6 Dec 2021
Thank you for your answer.
You cannot attach native C/C++ memory to an mxArray.
I obviously missed that bit. It could be good to add this infor to the "Fill mxArray in C MEX File" of the documentation.

Sign in to comment.

More Answers (0)

Products


Release

R2021a

Community Treasure Hunt

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

Start Hunting!

Translated by