.mex File crashes when executed in rapid succession
2 views (last 30 days)
Show older comments
Conrad Reschop
on 15 Nov 2017
Commented: Conrad Reschop
on 11 Dec 2017
Hey guys!
I have a rather strange problem with a .mex file I wrote. The purpose of the .mex file is to collect a varying number of elements out of a buffer, which is stored in a shared memory object.
When run just once there are no errors and it works as it should. But the .mex file will be executed several times a second, and that's when the trouble starts. As soon as it is executed (or at least called) more than once a second (and ideally it would be executed at least 10 times a second) Matlab just crashes without giving any information.
I'm quite sure it has something to do with the following line, where the mxArray* toPut is filled via double* pointer:
pointer[(iField + iSensor * 11) * bufferSize + iElement] = responseContainer[iField];
When commented out, the file works - but i obviously get an empty array.
The size of the array is rather big, it has to store 50*264 doubles the first time the mex file is executed and collects the content of the buffer. The buffer is then filled again, but even if the .mex file collects just once a second, there will be less than 50 new elements in the buffer - so the faster the .mex file is rerun, the smaller the array sizes get.
Nevertheless, i suppose it has something to do with memory management. I'm not sure if maybe ' pointer' isn't cleared quick enough from memory?
Obviously, i tried to find a solution by looking through various forums but to no avail.
I did my best checking that the datatypes are compatible and tried to work as close to the mathworks manuals and examples as possible. I also tried various ways of clearing the memory in the .mex file and between calls to the .mex file, but i'm not able to find a robust, crashfree solution.
Maybe anyone already encountered a similar problem or is able to point out an obvious mistake in my code.
Thanks for having a look!
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include "dataBuffer.h"
#include <iostream>
#include <mex.h>
using namespace boost::interprocess;
bool exists() {
try
{
shared_memory_object smo( open_only, "dataStorage", read_only );
}
catch (const interprocess_exception &ex) {
return false;
}
return true;
}
void mexFunction(
int nlhs,
mxArray *[],
int nrhs,
const mxArray *prhs[]
)
{
float responseContainer[11];
int status;
const int bufferSize= 5;
ndiDataElement currDataElements[bufferSize];
int nNoElements;
if (exists()) {
shared_memory_object smo( open_only, "dataStorage", read_write );
mapped_region mappedReg( smo,read_write );
double nanVal = mxGetNaN();
dataBuffer* buffer = static_cast<dataBuffer*>(mappedReg.get_address());
nNoElements = buffer->collectElementsAndReset(currDataElements);
mxArray* toPut = mxCreateDoubleMatrix((mwSize)nNoElements,(mwSize) 24*11, mxREAL);
double* pointer = mxGetPr(toPut);
for (int iElement = 0; iElement < nNoElements; iElement++){
for (int iSensor = 0; iSensor < 24; iSensor++){
currDataElements[iElement].getDataForSensor(iSensor,responseContainer);
for (int iField = 0; iField < 11; iField++){
if (responseContainer[iField] != BAD_FLOAT){
pointer[(iField + iSensor * 11) * bufferSize + iElement] = responseContainer[iField];
}
else {
pointer[(iField + iSensor * 11) * bufferSize + iElement] = nanVal;
}
}
}
}
status = mexPutVariable("caller", "serverData", toPut);
mxDestroyArray(toPut);
}
else {
mexPrintf("SMO doesn't exist!\n");
}
}
0 Comments
Accepted Answer
Cris Luengo
on 6 Dec 2017
pointer[(iField + iSensor * 11) * bufferSize + iElement]
should probably be
pointer[(iField + iSensor * 11) * nNoElements + iElement]
More Answers (0)
See Also
Categories
Find more on Performance and Memory 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!