MATLAB: How to read back (and use) a matrix from a matlab function called from a mex file

mexmexcallmatlabmxgetpr

I want to read back a matrix from a matlab function called from a mex file and I have been getting a segmentation violation when I try to run it. (At least my assumption is that it is related to how I am reading the matrix; I'm not exactly sure)
Here is an example representing what I am trying to do: (apologies if I include unnecessary detail, I am a novice mex user)
void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[]){
int ncols=210;
int mrows=210;
int i,j,
double ** a;
double ** b; // matrix to hold matlab output
mxArray * histforce_ips[1];
mxArray * histforce_ops[1];
// allocate memory:
a=(double**)malloc(mrows*sizeof(double *));
b=(double**)malloc(mrows*sizeof(double *));
for(i=0;i<mrows;i++){
a[i]=(double*)calloc(ncols,sizeof(double));
b[i]=(double*)calloc(ncols,sizeof(double));
}
// put something into a:
// ...
// pass a to matlab function
for(i=0;i<ncols;i++){
for(j=0;j<mrows;j++){
(mxGetPr(histforce_ips[0]))[i*mrows+j]=a[j][i];
}
}
// call function:
mexCallMATLAB(1,histforce_ops,1,histforce_ips,"calchistforce");
// extract data
for(i=0;i<ncols;i++){
for(j=0;j<mrows;j++){
b[j][i]=(mxGetPr(histforce_ops[0]))[i*mrows+j];
}
}
// free memory
for(i=0;i<mrows;i++){
free(a[i]);
free(b[i]);
}
free(a); free(b);
}
Thank you for your help.
N

Best Answer

I don't see anywhere in your code where you create a variable in histforce_ips[0]. E.g.,
mxArray * histforce_ips[1];
:
mexCallMATLAB(1,histforce_ops,1,histforce_ips,"calchistforce");
There is nothing inbetween these lines that sets histforce_ips[0] to anything, so when you call mexCallMATLAB you are passing an invalid pointer for the input argument. You need to do something like this instead:
mxArray * histforce_ips[1];
:
histforce_ips[0] = mxCreateDoubleMatrix(mrows,ncols,mxREAL);
:
// Then fill in the values of histforce_ips[0] via mxGetPr etc
:
mexCallMATLAB(1,histforce_ops,1,histforce_ips,"calchistforce");
:
mxDestroyArray(histforce_ips[0]);
mxDestroyArray(histforce_ops[0]);
Also, I don't know if this will eventually make a difference in your code at some point, but the way you allocate your "a" and "b" matrices piecemeal means that the memory for them is not guaranteed to be contiguous. Generally, if you want to preserve the a[j][i] syntax of indexing I would recommend allocating a single block of memory and work with that instead. E.g.,
// allocate memory:
a=(double**)malloc(mrows*sizeof(double *));
b=(double**)malloc(mrows*sizeof(double *));
a[0] = (double *) malloc(mrows*ncols*sizeof(double));
b[0] = (double *) malloc(mrows*ncols*sizeof(double));
for(i=1;i<mrows;i++){
a[i] = a[i-1] + ncols;
b[i] = b[i-1] + ncols;
}
:
free(a[0]); free(a);
free(b[0]); free(b);