Mex file crash after many run
Show older comments
Hi,
I have a mex function which I am using in a loop. After many iterations matlab gives access violation error and crashes. When I did a little search I found out that it may be resulting from memory allocation. Is there any way to define inputs and outputs differently that I will not get this crash problem? Or should I search for the solution somewhere else in the c code?
Thank you.
Ezgi Köker
void mexFunction(int nlhs, mxArray *plhs[], int nrhs,
const mxArray *prhs[])
{
double *altsin, *ustsin,
*altkis, *ustkis,
*xx, *xi, *fonk,
*afr, *mrg, *y, *x, *qs, lo;
long *ndeg, *lver,
*gedeg, edeg, ferti, kac,
nx, ny, nyi, amac;
int a, b;
int sonuc;
int carpan=0,i;
/* Defining inputs */
nx = mxGetScalar(prhs[0]);
ny = mxGetScalar(prhs[1]);
nyi = mxGetScalar(prhs[2]);
amac = mxGetScalar(prhs[3]);
ndeg = mxGetData(prhs[4]);
altsin = mxGetPr(prhs[5]);
ustsin = mxGetPr(prhs[6]);
altkis = mxGetPr(prhs[7]);
ustkis = mxGetPr(prhs[8]);
xi = mxGetPr(prhs[9]);
lo = mxGetScalar(prhs[10]);
a = (int)nvars_in+1;
b = (int)nfun_in+1;
/* Defining outputs */
plhs[0] = mxCreateDoubleMatrix(1,a, mxREAL);
xx = mxGetPr(plhs[0]);
plhs[1] = mxCreateDoubleMatrix(1,b, mxREAL);
fonk = mxGetPr(plhs[1]);
plhs[2] = mxCreateDoubleMatrix(1,b, mxREAL);
afr = mxGetPr(plhs[2]);
plhs[3] = mxCreateDoubleMatrix(1,b, mxREAL);
mrg = mxGetPr(plhs[3]);
plhs[4] = mxCreateNumericMatrix(1,a, mxUINT32_CLASS, mxREAL);
lver = mxGetData(plhs[4]);
plhs[5] =mxCreateNumericMatrix(1,b, mxUINT32_CLASS, mxREAL);
gedeg = mxGetData(plhs[5]);
plhs[6] =mxCreateDoubleMatrix(1,1, mxREAL);
qs = mxGetPr(plhs[6]);
sevket( nx, ny, nyi, amac,
ndeg, altsin, ustsin, altkis, ustkis,
xx, xi, fonk, mrg, lver,
redgr, gedeg, edeg, ferti, kac,
carpan, sonuc, sonuc, a, b, qs, lo);
}
Accepted Answer
More Answers (3)
ezgi koker
on 22 Jun 2017
0 votes
1 Comment
Jan
on 22 Jun 2017
You can still import the data in the exact type they are store in Matlab at first and convert them in the next step:
int32_T *nxI; % This is a pointer!
long nx;
nxI = (int32_T *)mxGetData(prhs[0]);
nx = (long) *nxI;
While:
plhs[1] = mxCreateDoubleMatrix(1,b, mxREAL);
fonk = mxGetPr(plhs[1]);
is fine, when you do not access more than fonk[b-1], this is suspicious:
plhs[4] = mxCreateNumericMatrix(1,a, mxUINT32_CLASS, mxREAL);
lver = mxGetData(plhs[4]);
A long is defined as:
Long signed integer type. Capable of containing at least the
[−2,147,483,647, +2,147,483,647] range;
at least! It can be a 64 bit integer also and then the code can crash. It depends on the compiler, what an "int" or "long" is, but in Matlab an int32 has the type int32_T on all Matlab versions, operating systems and processors. Do not mix the flexible and fixed definitions, because this causes troubles very often and reliably.
Even if te part is written by someone else, it is currently crashing and you cannot trust the results if if it ran without a crash. The code needs a re-design.
ezgi koker
on 29 Jun 2017
0 votes
1 Comment
Jan
on 29 Jun 2017
Please post the code. How did you allocate the ndeg array? mxAlloc?
ezgi koker
on 2 Jul 2017
Edited: Jan
on 4 Jul 2017
2 Comments
ezgi koker
on 4 Jul 2017
@ezgi koker: You could not format the code properly? I've done this for you this time: I've selected the code with the mouse and hit the "{} Code" button. This has been explained thousands of times in the forum, see e.g. How to use Markup.
This is the section for answers. It would be more useful to add all information required for understanding the problem in the section for the question. Leave it here this time, and for questions in the future, please care for posting all relevant details in the question, e.g. by appending new details marked by "[EDITED]".
You code still contains:
long *ndeg;
ndeg = mxGetPr(prhs[4]);
As I've mentioned already, this will drive you into troubles, because mexGetPr replies a pointer to a double array. You cannot be sure, that you long array uses the same number of bits. If long is a 32 bit integers, this code must crash. Don't do this. It is not clear, which type the 5th input has, but if it is a double, use:
double *ndeg_d;
long *ndeg;
int i, n_ndeg;
ndeg_d = mxGetPr(prhs[4]);
n_ndeg = (int) mxGetNumberOfElements(prhs[4]);
ndeg = mxAlloc(n_ndeg * sizeof(long));
for (i = 0; i < n_ndeg; i++) {
ndeg[i] = (long) ndeg_d[i];
}
Note that such data copies and conversion will take a lot of time. For efficient code, this should be avoided. The clean and fast solution would to compile the code such, that it accepts the data types provided by Matlab, and not to convert the data twice.
Another example for the cofusion of types:
long *gedeg;
plhs[5] = mxCreateNumericMatrix(1,b, mxUINT32_CLASS, mxREAL);
gedeg = mxGetData(plhs[5]); % mxGetData replies a void *
inside sevket gedeg is used as array of type long. Are you sure, that long is a UINT32?
I prophesize that your code will crash until you fixed it using the reliably defined data types int32_T and so on instead of long. Even if you can manage the code to run on your computer, it might fail with a new compiler or on a different machine.
C is fragile and you see that mixing the fixed defined Matlab classes and the compiler dependent types like long and int let the code crash. In all other threads concerning these problems in Mex functions, using the strictly defined classes like uint32_T fixed the problems immediately. Therefore I consider this as the best, most reliable and efficient solution and suggest it again. It will be much easier to adjust the code of sevket, than to struggle with the inconsistencies of calling the function.
Categories
Find more on Write C Functions Callable from MATLAB (MEX Files) in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!