0

[environment]

OS: OSX10.11 and maxOS Sierra(10.12)

MATLAB: matlab2013a and matlab2016a

Xcode: xcode7 and xcode8


In my work, I must use the following mex file in the old package.

//destructiveMatrixWriteAtIndices.c
//------------------------------------------------------
#include <matrix.h>  /* Matlab matrices */
#include <mex.h>
#include <stddef.h>  /* NULL */
#define notDblMtx(it) (!mxIsNumeric(it) || !mxIsDouble(it) || mxIsSparse(it) || mxIsComplex(it))
void mexFunction(int nlhs,       /* Num return vals on lhs */
                 mxArray *plhs[],    /* Matrices on lhs      */
                 int nrhs,       /* Num args on rhs    */
                 const mxArray *prhs[]     /* Matrices on rhs */
                )
{
 double *mtx;
 double *newValues;
 double *doubleStartIndex;
 int i, startIndex, size; 
 mxArray *arg;

 if (nrhs != 3) mexErrMsgTxt("requires 3 arguments.");

 /* ARG 1: MATRIX  */
 arg = prhs[0];
 if notDblMtx(arg) mexErrMsgTxt("MTX arg must be a real non-sparse matrix.");
 mtx = mxGetPr(arg);

 arg = prhs[1];
 if notDblMtx(arg) mexErrMsgTxt("MTX arg must be a real non-sparse matrix.");
 newValues = mxGetPr(arg);
 size = (int) mxGetM(arg) * mxGetN(arg);

 arg = prhs[2];
 if notDblMtx(arg) mexErrMsgTxt("MTX arg must be a real non-sparse matrix.");
 doubleStartIndex = mxGetPr(arg);
 startIndex = (int) doubleStartIndex[0];

 for (i=0; i<size; i++){  
     mtx[i+startIndex] = newValues[i];        
 }
 return;
}
//------------------------------------------------------

This mex file is the function to overwrite the scalar and the part of matrix through the pointer.

e.g. in matlab2013a command window (scalar in matlab2013a)

a = 1;
destructiveMatrixWriteAtIndices(a, 3, 0);

and the variable "a" becomes "3".

e.g. in matlab2013a and matlab2016a command window (matrix in matlab2013a and matlab2016a)

a = [1, 2];
destructiveMatrixWriteAtIndices(a, 3, 0);

and the variable "a" becomes "[3, 2]".

e.g. in matlab2016a command window (scalar in matlab2016a)

a = 1;
destructiveMatrixWriteAtIndices(a, 3, 0);

and the variable "a" becomes "1"! Why?

I also used the lldb, and revealed the strange behavior of this code.

In matlab2013a and matlab2016a, when I run the following snippet.

a = 1;
destructiveMatrixWriteAtIndices(a, 3, 0);

The lldb revealed "*mtx = 3" at the end of the mex function in both matlab, but the mex function couldn't pass the result(*mtx = 3, or prhs[0] = 3) through the pointer in the only matlab2016a.

It's very strange behavior!

※I have understood that this mex function is very danger, but this mex function was used at some points in the package that I must use. Therefore, I must fix this mex file and make the package run in matlab2016a.

Please help me.

rvkH7sfa3
  • 3
  • 1

1 Answers1

0

I'm pretty sure you're not meant to modify the input array in a mex function. More details here Does Matlab ever copy data passed to a mex function?. The "matlab" solution is probably to return the modified array as an output of the mex rather modifying in place.

Community
  • 1
  • 1
MarkV
  • 1,030
  • 7
  • 15
  • Thank you for telling me the useful information. I had to use some old MATLAB package and I wanted to do small correction as much as possible, but now, I understood this mex routine is useless and dangerous anymore. Thus, I will rewrite some sections containing this mex routine by using normal MATLAB indexing. – rvkH7sfa3 Oct 09 '16 at 11:01