MATLAB: MATLAB crashes with C++ Class used in mex-file

c

Hello,
I want to use a user defined C++ library within MATLAB via mex-files. This library uses a C++ Class called MODEL with only data member in it (int, double, 2-dimensional arrays). The constructor uses the new operator to allocate memory. All computational routins of this library read and write to an object of this class called MODEL m1 and calculate some result vectors to return to MATLAB. To fill the object of class MODEL m1 with data values, I send a MATLAB structure from MATLAB to the mex-file and fill each data member with the data fields of the MATLAB structure. In my mexfile I do not use the destructor with delete command inside due to the Memory Considerations For Class Destructors from MATLAB Documentation.
After the successful run of the computational routine, the result vector is returned to MATLAB. After that, MATLAB sometimes crashes with a "corrupted double-linked list" error or Segmentation fault error. Sometimes there is no error at the end of the mex-file run. I run the mex file in MATLAB debug mode -Dgdb.
Do somebody know where to finde the error?
I guess, there must be some memory management violation between MATLAB memory management and the C++ memory management.
Are there some examples using C++ classes with mex-files and multi-dimensional array data member? I did not find a good example from MATLAB documentation.
Below, a short example of my mex-file:
#include <mex.h>
#include <stdio.h>
#include <iostream>
#include <cmath>
using namespace std;
#include "./spd/include/spd.h"
#include "./spd/include/rot.h"
#include "./spd/include/spn.h"
#include "./spd/matrix/matrix.h"
#include "./spd/matrix/vector.h"
/* Computational Routine from C++ Library */
void kin_( double *r0, double *ORI_0, double *q_in, double *B_EE, double *ORI_EE, MODEL& m)
{
B_EE[0]=1.0;
B_EE[1]=2.0;
B_EE[2]=3.0;
m.LINKNUM = 8;
calc_SP( m ); // C++ library function with temp variables (allocated with new/delete)
matrix_cpy( 3, 1, m.POS_e[1], B_EE ); // C++ library function which copies vecotr m.POS_e[1] in to B_EE
}
/* the gateway function */
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
double *r0,*ORI_0, *q_in , *B_EE, *ORI_EE;
static MODEL m1;
m1.constructor();
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// +++++++++++ copy each field of class MODEL m1 from Matlab into mexFunction
double value_in_LINKNUM_field, value_in_E_NUM_field, value_in_BB_field, value_in_EE_field;
mxArray *field_LINKNUM_ptr, *field_E_NUM_ptr, *field_BB_ptr , *field_EE_ptr ;
// copy LINKUM into mexFunction
field_LINKNUM_ptr = mxGetField(prhs[0],0,"LINKNUM");
value_in_LINKNUM_field = mxGetScalar(field_LINKNUM_ptr);
m1.LINKNUM = value_in_LINKNUM_field;
// copy E_NUM into mexFunction
field_E_NUM_ptr = mxGetField(prhs[0],0,"E_NUM");
value_in_E_NUM_field = mxGetScalar(field_E_NUM_ptr);
m1.E_NUM = value_in_E_NUM_field;
// copy BB into mexFunction [1x7]
field_BB_ptr = mxGetField(prhs[0],0,"BB");
value_in_BB_field = mxGetScalar(field_BB_ptr);
for(int k=0;k<m1.LINKNUM-1; k++)
{
m1.BB[k] = (int)value_in_BB_field+k;
}
// copy Qe into mexFunction [2x3]
l=0;
field_Qe_ptr = mxGetField(prhs[0],0,"Qe"); // returns pointer to the field of structure
mxArray *mxPtr_Qe = (mxArray*)field_Qe_ptr;
double *dPtrQe = mxGetPr(mxPtr_Qe);
for(int j=0;j<3; j++)
{
for(int k=0;k<m1.E_NUM; k++)
{
m1.Qe[k][j] = *(dPtrQe+l);
l++;
}
}
//..... more field arrays copied into class MODEL m1....
// +++++++++ end of copy structure into class MODEL m1
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/* create a pointer to the input vector r0 */
r0 = mxGetPr(prhs[1]);
/* create a pointer to the input matrix ORI_0 */
ORI_0 = mxGetPr(prhs[2]);
/* create a pointer to the input vector q_in */
q_in = mxGetPr(prhs[3]);
/* set the output pointer to the output matrix B_EE*/
plhs[0] = mxCreateDoubleMatrix(3,1, mxREAL);
/* create a C pointer to a copy of the output matrix CB_EE*/
B_EE = mxGetPr(plhs[0]);
plhs[1] = mxCreateDoubleMatrix(3,3, mxREAL);
/* create a C pointer to a copy of the output matrix ORI_EE */
ORI_EE = mxGetPr(plhs[1]);
/* call the C subroutine */
kin_(r0, ORI_0, q_in, B_EE, ORI_EE, m1 );
// no destructor!!!!
//m1.destructor();
}
The Class MODEL is defined in model.h:
#include <iostream>
using namespace std;
#include "../include/define.h"
#include "../include/common.h"
class MODEL{
public:
/* Load Parameters */
int LINKNUM, E_NUM;
int *BB; // Link connectivity
int *EE; // end effector
Vector3 *Qe; // Vector3 is defined in common.h as "typedef double Vector3[3];"
// ... more data member allocations ....
//_/_/_/ constructor of arrays _/_/_//
void constructor()
{
BB = new int[LINKNUM];
EE = new int[LINKNUM];
// link
Qe = new Vector3[LINKNUM];
.
// ... more data memeter ....
}
//_/_/_/ destructor of arrays _/_/_//
void destructor()
{
delete [] BB;
delete [] EE;
// link
delete [] Qe;
}
};
Thank`s a lot! Greetings

Best Answer

The section "Memory Considerations For Class Destructors" recommends not to clear memory that is managed by MATLAB. In other words, any mxArrays that you create in the class are placed in MATLAB-managed memory which is cleared by MATLAB when the MEX-function exits due to an error - therefore, you shouldn't directly destroy them in your destructor. However, your class members are of built-in type and not managed by MATLAB - so I think that you should call m1.destructor() at the end of execution.
Please also not that your class method called destructor() is not the same as ~MODEL() - therefore, even if you were managing mxArrays as class members, you would still need to call m1.destructor() at the end of your MEX-function. The documentation section that you cite talks about not calling mxFree or mxDestroyArray in ~MODEL(), but you still need to clean-up the arrays manually in the event that an error did not occur, and MATLAB did not perform an automatic cleanup.