Quantcast
Channel: Active questions tagged crash - Stack Overflow
Viewing all articles
Browse latest Browse all 7193

Matlab crash after returning from function that calls MEX

$
0
0

SOVED by @CrisLuengo and @JamesTursa.Solution at the end of the post


Original Post

I'm creating a MEX to find a path between two nodes using the A* algorithm. The code works as expected, retrieves the right result and everything seems to be fine, but when I return from the method that calls the MEX, Matlab simply shuts itself down.

As I know sometimes Matlab creates a pointer to the same memory address when the user tries to create a copy of a variable (I.E. A = 3; B = A, then A and B are pointing to the same memory address, even though Matlab shows them as 2 independent variables) I used an old trick that consists on performing an operation directly to the copy of the variable, even if its a silly one, Matlab will think that the two variables are no longer the same and will create a copy of it (I.E. A = 3; B = A; B = B+0, now A and B are stored as different and independent variables).

So the only way that I have found to fix the issue is to do what is shown below in function getWP:

function testAStarC()    % load the map of the area    load('epsp0_2_nav.mat');    % Set the initial node    initNode = '16x21';    % Set the target node    finalNode = '-15x54';    % Select Heuristic    heuristic = 'Manhattan';    % Create a target location (targetX, targetY, targetAngle)    targetCoords = [-15*110  54*110 0.15];    % Function that hosts the call to the MEX    wp = getWP(map, initNode, finalNode, targetCoords, heuristic);    disp('If you remove the line cellNodes{keyID}.x = cellNodes{keyID}.x; from getWP ...        I wont reach this line');    disp(['Route with ',num2str(length(wp)),' wp found']);    disp('done');function waypointsList = getWP(map, initNode, finalNode, targetCoords, heuristic)    % HashMap containing the nodes (this is a Java hashmap)    nodesHash = map.navMap.nodes.nodes;    keys = nodesHash.keys();    numNodes = length(keys);    cellNodes = cell(1,numNodes);    % Parse the nodes from the HashMap to Cells as the MEX seems to be    % unable to read directly from the Java HashMap    for keyID=1:numNodes        cellNodes{keyID} = nodesHash(keys{keyID});        %---------------------------------------------------------        % WITHOUTH THIS MATLAB CRASHES WHEN RETURNING FROM GETWP        %---------------------------------------------------------        % We need this to force Matlab to create a new copy of the content,        % otherwise will send a pointer aiming to the HashMap and crash when        % returning from getWP.        cellNodes{keyID}.x = cellNodes{keyID}.x;    end    waypointsList = AStar(cellNodes, initNode, finalNode, targetCoords, heuristic, 1);    disp('I am not crashing here if you remove cellNodes{keyID}.x = cellNodes{keyID}.x');

My first thought was that I was doing something wrong to "cellNodes" inside the MEX and this was causing Matlab to crash, but I am not performing any operations using directly the input parameter. This is the constructor for the Node class:

Node.cpp

Node::Node(mxArray *cellElement){    double *xIn;    double *yIn;    char strIn[15];    double *posXIn;    double *posYIn;    double *weightIn;    double *tempVal;    size_t numCellElms;    mxArray *cellElement2;    numCellElms = mxGetNumberOfFields(cellElement);    size_t size;    for (int cellItem = 0; cellItem < numCellElms; cellItem++)    {        cellElement2 = mxGetCell(cellElement,cellItem);        if (cellItem == 0)        {            xIn = mxGetPr(cellElement2);            memcpy(tempVal,xIn,sizeof(double));            gridX = int(*tempVal);        }        if (cellItem == 1)        {            yIn = mxGetPr(cellElement2);            memcpy(tempVal,yIn,sizeof(double));            gridY = int(*tempVal);        }        if (cellItem >= 2 && cellItem < 10)        {            mwSize buflen = mxGetN(cellElement2)*sizeof(mxChar)+1;            if (buflen <= 1)            {                connections[cellItem-2][0] = '\0';            }            else            {                mxGetString(cellElement2, strIn, buflen);                memcpy(&connections[cellItem-2][0], strIn, buflen);                          }        }        if (cellItem == 10)        {            posXIn = mxGetPr(cellElement2);            memcpy(&posX,posXIn,sizeof(double));                    }                        if (cellItem == 11)        {            posYIn = mxGetPr(cellElement2);            memcpy(&posY,posYIn,sizeof(double));          }                if (cellItem == 12)        {            posXIn = mxGetPr(cellElement2);            memcpy(&wpX,posXIn,sizeof(double));                    }                        if (cellItem == 13)        {            posYIn = mxGetPr(cellElement2);            memcpy(&wpY,posYIn,sizeof(double));          }                        if (cellItem == 14)        {            weightIn = mxGetPr(cellElement2);            memcpy(&weight,weightIn,sizeof(double));                      }                                    }    sprintf(xStr,"%i",gridX);    sprintf(yStr,"%i",gridY);    sprintf(key,"%ix%i",gridX,gridY);}

And this is how I initialize the Nodes list inside the AStar.cpp

// Create nodes in the nodes hashmxArray *cellElement;std::map<std::string, Node> nodesHash;for (int nodeID=0; nodeID < numberOfNodes; nodeID++) {    cellElement = mxGetCell(prhs[0], nodeID);    Node n(cellElement);    nodesHash[n.key] = n;}

Form now on nothing uses prhs[0] anymore, as nothing has altered the content of the prhs[0] (variable containing the pointer to the Matlab variable cellNodes), this variable should be exactly the same after leaving the MEX.

From here I have two questions:

  1. If nothing is altering the content of the first parameter, why should it crash when returning from getWP?
  2. Is there a more elegant way of forcing Matlab to create a real copy of a variable?

Thanks!

*Edit1: Using Matlab 2015b in Windows10 64 bit.


Solution

[Node.cpp] 'double* tempVal' was not allocated, although the code worked, this was possibly messing with the integrity of prhs[0] thus causing Matlab to crash when returning from the function that invoked the MEX.

The solution was to declare tempVal as 'double tempVal[1]'.After that, the testAStarC.m the line 'cellNodes{keyID}.x = cellNodes{keyID}.x;' can be removed without causing the error.

Although unrelated to the crash, the use of memcpy to get scalar doubles has been replaced with mxGetScalar().

Node constructor:

Node::Node(mxArray *cellElement){    char strIn[15];    double tempVal[1];    size_t numCellElms = mxGetNumberOfFields(cellElement);    mwSize buflen;    for (int cellItem = 0; cellItem < numCellElms; cellItem++)    {        mxArray *cellElement2 = mxGetCell(cellElement,cellItem);        switch (cellItem)        {            case 0:                gridX = (int)mxGetScalar(cellElement2);                break;            case 1:                gridY = (int)mxGetScalar(cellElement2);                break;            case 2:            case 3:            case 4:            case 5:            case 6:            case 7:            case 8:            case 9:                buflen = mxGetN(cellElement2)*sizeof(mxChar)+1;                if (buflen <= 1)                    connections[cellItem-2][0] = '\0';                else                {                    mxGetString(cellElement2, strIn, buflen);                    memcpy(&connections[cellItem-2][0], strIn, buflen);                              }                break;            case 10:                posX = mxGetScalar(cellElement2);                        break;            case 11:                posY = mxGetScalar(cellElement2);                  break;            case 12:                wpX = mxGetScalar(cellElement2);                break;            case 13:                wpY = mxGetScalar(cellElement2);                    break;            case 14:                weight = mxGetScalar(cellElement2);                break;        }    }    sprintf(xStr,"%i",gridX);    sprintf(yStr,"%i",gridY);    sprintf(key,"%ix%i",gridX,gridY);}

testAStarC.m

function waypointsList = getWP(map, initNode, finalNode, targetCoords, heuristic)    % HashMap containing the nodes (this is a Java hashmap)    nodesHash = map.navMap.nodes.nodes;    keys = nodesHash.keys();    numNodes = length(keys);    cellNodes = cell(1,numNodes);    % Parse the nodes from the HashMap to Cells as the MEX seems to be    % unable to read directly from the Java HashMap    for keyID=1:numNodes        cellNodes{keyID} = nodesHash(keys{keyID});    end    waypointsList = AStar(cellNodes, initNode, finalNode, targetCoords, heuristic, 1);

Viewing all articles
Browse latest Browse all 7193

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>