Simple mex file crash?

2 views (last 30 days)
Alberto Paniate
Alberto Paniate on 24 Mar 2022
Edited: James Tursa on 25 Mar 2022
Hi I am studying mex files. I am trying to write a simple mex file that does a sum of two elements.
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
double *outData, *inData;
if(nrhs!=2) mexErrMsgTxt("Missing input data.");
inData = mxGetDoubles(prhs[0]);
outData = mxGetDoubles(plhs[0]);
outData[0] = inData[0]+inData[1];
}
If I try to run it, matlab crashes. There is some problem with the last line, have you any suggestion?

Answers (2)

Rik
Rik on 24 Mar 2022
Despite what you indicate in the 4th line, inData and outData are not actually double*, they are mxDouble*.
As you can see in the documentation for mxGetDoubles, the output type is mxDouble*, which is a pointer type. You can add up two pointers, but that doesn't add up the values those pointers are pointing to.
A second problem with your code is that you assume inData will have two elements, while the rest of your post looks like you want to add up two inputs. The below code is the Matlab equivalent of what you're trying.
function outData=test(rhs1,rhs2)
if nargin~=2,error('Missing input data'),end
inData=rhs1;
outData=inData(1)+inData(2);
end

James Tursa
James Tursa on 25 Mar 2022
Edited: James Tursa on 25 Mar 2022
You need to create the output variable yourself. plhs[0] doesn't exist until you create it, thus this line crashes:
outData = mxGetDoubles(plhs[0]);
because plhs[0] is garbage at this point and you are dereferencing an unitialized pointer.
Your code needs to look something like this instead if you want to add up two values from a single input:
/* Equivalent to m-code: Output = Input(1) + Input(2) */
/* The Input needs to have at least 2 elements */
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
double *outData, *inData;
if(nrhs!=1) mexErrMsgTxt("Missing input data.");
if(nlhs>1) mexErrMsgTxt("Too many outputs.")
if( !mxIsDouble(prhs[0]) || mxIsComplex(prhs[0]) || mxIsSparse(prhs[0]) ||
mxGetNumberOfElements(prhs[0])<2) {
mexErrMsgTxt("Need one full real double input with at least two elements")
}
plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL); /* You need to create plhs[0] first */
inData = mxGetDoubles(prhs[0]);
outData = mxGetDoubles(plhs[0]);
outData[0] = inData[0] + inData[1];
}
If you want to add up two scalar inputs, then the code would look something like this instead:
/* Equivalent to m-code: Output = Input1 + Input2 */
/* Both inputs need to have at least 1 element */
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
double *outData, *inData0, *inData1;
if(nrhs!=2) mexErrMsgTxt("Missing input data.");
if(nlhs>1) mexErrMsgTxt("Too many outputs.")
if( !mxIsDouble(prhs[0]) || mxIsComplex(prhs[0]) || mxIsSparse(prhs[0]) ||
mxGetNumberOfElements(prhs[0])<1) {
mexErrMsgTxt("Need two full real double inputs with at least one element each")
}
if( !mxIsDouble(prhs[1]) || mxIsComplex(prhs[1]) || mxIsSparse(prhs[1]) ||
mxGetNumberOfElements(prhs[1])<1) {
mexErrMsgTxt("Need two full real double inputs with at least one element each")
}
plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL); /* You need to create plhs[0] first */
inData0 = mxGetDoubles(prhs[0]);
inData1 = mxGetDoubles(prhs[1]);
outData = mxGetDoubles(plhs[0]);
outData[0] = inData0[0] + inData1[0];
}
As a side note, if you are just returning a scalar double from your mex routine then you might consider mxCreateDoubleScalar( ), which is a bit simpler to use than the pointer code you have written.

Community Treasure Hunt

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

Start Hunting!