Matlab crashes when manipulating an array generated by a mex function

Dear all,
I have written a Mex-function that generates an array. Actually, it is a topological sort algorithm. Now let's say I call this function
A = tsort(B); % contains a call to the mex function
A = otherfunction(A); % other function that modifies A contains only matlab code
then it happens quite often that Matlab crashes when calling otherfunction, even after minutes between my call to tsort and otherfunction. Did anyone experience such problems with his or her code. By the way, I am using Windows 7 64bit, Matlab 2012a and Microsoft Software Development Kit (SDK) 7.1 as compiler.
Thanks for your help, Anon

댓글 수: 8

We will probably need to see your tsort() code.
There are some common errors that people tend to make in mex code that show up the next time that MATLAB tries to allocate or deallocate memory, such as if another function is called.
Thanks for your reply, Walter. Here is the c-code. I have included a minimal example in the help text that hopefully outlines, what the algorithm does.
// file: tsort_mex.c
// steepest gradient
// inp 1: SE (steepest downward neighbor grid, uint32)
// matrix with, e.g.
// [4 0 4 7;
// 4 4 4 7;
// 5 5 8 8];
// indicates that cell 1 drains to 4, cell 2 drains
// to 4 and cell 9 to 8 etc... Cells with SE == 0 don't
// drain anywhere
// inp 2: seed pixels (linear index, uint32)
// above example 4
// inp 3: nr of missing values (scalar, double)
// above example 0
//
// outp 1: topological order list of linear indices (uint32)
// above example: 12 9 6 3 11 8 5 2 10 7 1
// outp 2: linear indices of the childs of outp 1 (uint32)
// above example: 8 8 5 5 7 7 4 4 4 4 4
#include "mex.h"
#include "matrix.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
mwSize nrc, nrow, ncol;
mwIndex IX, IXN, neigh, row, col, r, c, nrLM, pix1, pix2, pLM;
int coln[8] = {0, 1, 1, 1, 0, -1, -1, -1};
int rown[8] = {-1, -1, 0, 1, 1, 1, 0, -1};
int *SN, *ix, *ixc, *LOCALMINIMA, *MV;
if( nrhs > 3 || nlhs > 2 ) {
mexErrMsgTxt("Need 3 inputs and no more than 2 output");
}
// input data
SN = mxGetData(prhs[0]);
nrow = mxGetM(prhs[0]);
ncol = mxGetN(prhs[0]);
nrc = nrow*ncol;
LOCALMINIMA = mxGetData(prhs[1]);
nrLM = mxGetNumberOfElements(prhs[1]);
MV = mxGetData(prhs[2]);
// output
plhs[0] = mxCreateNumericMatrix((mwSize) nrow*ncol - nrLM,(mwSize) 1, mxUINT32_CLASS, mxREAL);
plhs[1] = mxCreateNumericMatrix((mwSize) nrow*ncol - nrLM,(mwSize) 1, mxUINT32_CLASS, mxREAL);
ix = mxGetData(plhs[0]);
ixc = mxGetData(plhs[1]);
// set initial pointer locations
pix1 = (nrc-nrLM-MV[0]-1);
pix2 = (nrc-nrLM-MV[0]-1);
pLM = 0;
// IX = LOCALMINIMA(pLM)
IX = LOCALMINIMA[pLM] - 1;
while (pix1 >= 0) {
row = IX%nrow;
col = (IX-row)/nrow;
for ( neigh = 0; neigh < 8; neigh++ ) {
// row index of neighbor
r = row + rown[neigh];
// column index of neighbor
c = col + coln[neigh];
// potential neigbhor outside grid boundaries?
// if yes, go back to beginning of the for loop
if (r<0 || r >= nrow || c < 0 || c >=ncol) {
continue;
}
IXN = c*nrow + r;
if (SN[IXN] == (IX+1)) {
ixc[pix1] = (int) IX+1;
ix[pix1] = (int) IXN+1;
pix1 = pix1-1;
}
}
// no upslope neighbor
if (ix[pix2] == 0) {
pLM = pLM +1;
if (pLM > nrLM) {
return;
}
IX = LOCALMINIMA[pLM] -1;
} else {
IX = ix[pix2] - 1;
pix2 = pix2-1;
}
}
return;
}
Anyone ideas?
Probably several people have looked at this post and had the same reaction that I had. Basically, it is not obvious from looking at the code where the indexes used would become invalid. So I would suggest putting in a lot of checks in the code to detect a problem and print it out. Everywhere you index into an array, put a check. E.g., check to see that SN, ix, ixc, and MV are not NULL. Check to see that IXN is not too large just before you do SN[IXN]. Check to see that pix1 is not too large just before before you do ixc[pix1] and ix[pix1]. Etc. My guess is that eventually you will get a message to the screen telling you where the problem is.
James,
thanks for your reply. Your suggestion seems to me applicable only when the function itself throws an error? But does it also apply to the problem that the output arrays are generated and their later manipulation results in a crash? This is the first piece of c-code I have ever written, so I am quite unexperienced with debugging it...
My first guess was that there is a problem with the address space allocated to the variables and I came across mxfree. I didn't use mxfree in my code. Could this be a reason?
Cheers, Anon
Just an idea to check. Your mexFunction gives back Data of type
mxUINT32_CLASS
Matlab use double as standard, as far as I know. I do convert integers, which should be given back to matlab from my mexFunction, to doubles before. Otherwise you have to work with int32() in matlab. This is just an idea...
Hi Colin,
I intend to work with uint32 in Matlab, since some of matrices I work with require large amounts of memory.
Thanks, Anon
@anon: The mex function is likely corrupting memory but that corruption isn't detected until later on after the mex routine has returned control back to MATLAB. E.g., the mex routine might have corrupted another variable in the workspace that has nothing to do with the mex routine, and it isn't until you get back to MATLAB and do downstream stuff that the error has an effect and crashes MATLAB. If you are unfamiliar with debugging then I suggest you follow my advice and put in lots of checks all over your code to detect when you are out-of-bounds or dereferencing a NULL pointer etc.

댓글을 달려면 로그인하십시오.

 채택된 답변

Jan
Jan 2013년 1월 24일
편집: Jan 2013년 1월 24일

1 개 추천

It is a bad idea to use int * pointers on a 64 bit system. mwSize and mwIndex is smarter and avoids the typical crashes.
When ix is a pointer to a UINT32 array, use a uint32_T * to access its elements instead of an int.
You check c to be smaller than 0, but are you sure than mwIndex is signed at all? If your algorithm required a signed type, use mwSignedIndex explicitly.
It is easy to write a C-Mex file, which corrupts the memory. Frequently the crash does not occur inside the C-Mex, because C is very tolerant to brute memory access, in opposite to Matlab.

댓글 수: 1

Thank you everyone for your replies. I have changed the pointer class and used mwSignedIndex as suggested by Jan. So far, I haven't experienced any crashes anymore.

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

도움말 센터File Exchange에서 Matrix Indexing에 대해 자세히 알아보기

태그

질문:

2013년 1월 22일

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by