MEX Crash due to dynamic memory allocation
4 views (last 30 days)
Show older comments
This is my first time attempting to convert a MATLAB function into a C++ executable. I am having difficulty dynamically allocating space to arrays that are created and used only within the MEX function. This is necessary because the function will be used in an iterative process in which the number of points of interest for the calculations will change. I am able to compile the code successfully in its current state, however,MATLAB crashes without any specific error when the function is run.
The purpose of this code is to calculate the stresses [s11, s22, s12] occurring between different points within a 2D domain. There are 8 coordinate frames of reference to be considered. The distance values passed in are already resolved into the reference frame of the specific point of interest. I have attache the entire script below with comments for clarity. I have also attached a Matlab script that should generate the inputs necessary for the MEX file.
#include <math.h>
#include <matrix.h>
#include <mex.h>
#include <iostream>
# define PI 3.1415926535897932
//MATLAB function definition
//[stress_11,stress_22,stress_12] = SMex(dXi_Rx,dXi_Ry,b_vec2,slip_sel,theta,h,mu,w,l,nu)
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
//declare variables
mxArray *g_out, *h_out, *i_out;
const mwSize *dims;
double *X_p, *Y_p, *b_p, *theta, *slip_p, *mu, *h_d, *nu, *w, *l, *s11, *s22, *s12;
int dimx, dimy, *slip;
int j,k,q,h,z, aridx, sidx;
//associate inputs
mxArray *dupArray[10];
for(aridx = 0; aridx < 10; ++aridx){
dupArray[aridx] = mxDuplicateArray(prhs[aridx]);
}
//figure out dimensions
dims = mxGetDimensions(prhs[0]);
dimy = (int)dims[0]; dimx = (int)dims[1];
//associate outputs
g_out = plhs[0] = mxCreateDoubleMatrix(1,dimx,mxREAL);
h_out = plhs[1] = mxCreateDoubleMatrix(1,dimx,mxREAL);
i_out = plhs[2] = mxCreateDoubleMatrix(1,dimx,mxREAL);
//associate pointers
X_p = mxGetPr(dupArray[0]);
Y_p = mxGetPr(dupArray[1]);
b_p = mxGetPr(dupArray[2]);
slip_p = mxGetPr(dupArray[3]);
theta = mxGetPr(dupArray[4]);
h_d = mxGetPr(dupArray[5]);
mu = mxGetPr(dupArray[6]);
nu = mxGetPr(dupArray[7]);
w = mxGetPr(dupArray[8]);
l = mxGetPr(dupArray[9]);
s11 = mxGetPr(g_out);
s22 = mxGetPr(h_out);
s12 = mxGetPr(i_out);
//Convert h_d from double to int for for loop
h = (int)h_d[0];
//Convert slip system values from double to int for switch structure
for(z=0;z<dimy;z++){
slip[z] = (int)slip_p[z];
}
//Declare Variables to be used in Stress calculations
//Dynamically allocate space as the number of points of interest will change
double term1, num, deno, s_term[3];
double b, X, Y;
int Ytemp, index;
double *s[3][8];
for(sidx = 0; sidx < 24; sidx){
s[sidx] = new double [dimx];
}
// Stresses are calculated at each dislocation, 11 identical domains are considered stacked ontop of one another.
for(j=0;j<=(2*h);j++)
{
Ytemp =(j-h);
for(k=0;k<dimx;k++)
{
for(q=0;q<dimy;q++)
{
index = k*dimy+q;
if(k == q){
s_term[0] = 0;
s_term[1] = 0;
s_term[2] = 0;
}
else{
b = b_p[q];
X = X_p[index]/(w[0]/2);
Y = Y_p[index]/(w[0]/2) + Ytemp;
term1 = mu[0]*PI*b/(2*PI*(1-nu[0])*w[0]);
num = 1-cos (PI*X)*cosh (PI*Y);
deno = 1/(cosh (PI*Y) - cos (PI*X));
s_term[0] = -1*term1*deno*(2*sinh (PI*Y) + PI*Y*num*deno);
s_term[1] = 0;
s_term[2] = 0;
}
// Stresses aributted to dislocations corresponding to the same slip system are summed
for (sidx = 0; sidx < 3; ++sidx){
qidx = slip[q];
s[sidx][qidx][k] = s[sidx][qidx][k] + s_term[sidx];
}
}
}
}
// Stresses are resolved into the reference coordinate frame and returned to MATLAB
for(k=0;k<dimx;k++){
for(q=0;q<8;q++){
s11[k] = s11[k] +cos(theta[q])*cos(theta[q])*s[0][q][k] + sin(theta[q])*cos(theta[q])*2*s[2][q][k] + sin(theta[q])*sin(theta[q])*s[1][q][k];
s22[k] = sin(theta[q])*sin(theta[q])*s[0][q][k] - cos(theta[q])*sin(theta[q])*2*s[2][q][k] + cos(theta[q])*cos(theta[q])*s[1][q][k] ;
s12[k] = -cos(theta[q])*sin(theta[q])*s[0][q][k] - (cos(theta[q])*cos(theta[q]) - sin(theta[q])*sin(theta[q]))*s[2][q][k] + cos(theta[q])*sin(theta[q])*s[1][q][k];
}
}
return;
}
5 Comments
Guillaume
on 29 Mar 2019
Edited: Guillaume
on 29 Mar 2019
@James, @morri
Well, it's been over 10 years since I wrote any C++, exact syntax is becoming hazy... Follow the spirit of the comment (also why i didn't post it as an answer), not the actual riddled with typos and oversight code.
@morri,
The idea with the 2nd and 3rd piece is to create a 3x8 array of pointers to array, so s[i][j] replaces your si_j and s[i][j][k] replaces your si_j[k]. The only thing is I forgot that the j index in your case is not q but slip[q], so:
for (sidx = 0; sidx < 3; ++sidx){}
qidx = (int)slip[q];
s[sidx][qidx][k] += s[sidx][qidx][k];
}
Oh, and I forgot to mention, the spacing in your
dimx* sizeof(*s11_1) %inside the MxMalloc calls
is extremely misleading. The first * is a multiplication but with that spacing it looks like a pointer declaration. The compiler is going to understand it fine, but you're going to confuse human readers.
Answers (1)
Robert Lummert
on 29 Mar 2019
Your function never checks nrhs>=1 but accesses prhs[0]. If called with no input argument, it should crash when accessing the non-existant input in line 29 already.
2 Comments
Robert Lummert
on 29 Mar 2019
Well, prhs[0] up to prhs[9], but yes, in that case the use of prhs shouldn't cause the crash.
See Also
Categories
Find more on Write C Functions Callable from MATLAB (MEX Files) in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!