MATLAB Answers

Why does mxSetDoubles crash this MEX file?

1 view (last 30 days)
Brian Bagenstose
Brian Bagenstose on 10 Dec 2019
Edited: James Tursa on 12 Dec 2019
Here's the MEX function:
#include "mex.h"
void myFun(double *a, int array_size)
{
int i;
for (i=0;i<array_size;i++)
a[i] = a[i]+1;
}
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
int array_size;
double *a;
array_size = mxGetNumberOfElements(prhs[0]);
a = mxGetDoubles(prhs[0]);
myFun(a,array_size);
plhs[0] = mxCreateDoubleMatrix((mwSize) 1,(mwSize) array_size, mxREAL);
mxSetDoubles(plhs[0],a);
}
The result is as follows:
>> mex -R2018a simpleEx.c
Building with 'Microsoft Visual C++ 2017 (C)'.
MEX completed successfully.
>> simpleEx([5 4 2])
ans =
6 5 3
>> simpleEx([5 4 2])
ans =
7 6 4
>> simpleEx([5 4 2])
* MATLAB crashes with no log file*
Why does the memory get "cached" so the second time, the results are one higher than expected? And why does mxSetDoubles crash everything on the third run? I know it's that function because if I comment it out, it doesn't crash and the output is just zero's.
Thanks!

  0 Comments

Sign in to comment.

Answers (1)

James Tursa
James Tursa on 11 Dec 2019
Edited: James Tursa on 12 Dec 2019
This line is crashing your code:
mxSetDoubles(plhs[0],a);
You can't re-use data pointers this way. You have essentially shared the data pointers between plhs[0] and prhs[0] but MATLAB doesn't know that they are sharing data pointers. So when one variable gets deleted the data pointer becomes invalid. And when the other variable (now having an invalid data pointer) tries to access the data pointer it crashes. (You also created a permanent memory leak but that is another issue).
In addition, you generally shouldn't modify the data of a prhs[ ] variable in place as that can affect other variables. So myFun( ) is non-conforming.
In general, you should use mxDuplicateArray to generate a plhs[0] variable, and then modify the data of that variable in-place. E.g.,
array_size = mxGetNumberOfElements(prhs[0]);
plhs[0] = mxDuplicateArray(prhs[0]);
a = mxGetDoubles(plhs[0]);
myFun(a,array_size);

  0 Comments

Sign in to comment.

Sign in to answer this question.

Tags

Products


Release

R2019b