Segfault when trying to use std::vector in mex function

1 view (last 30 days)
Hello all,
I am having a bit of a hard time resolving this issue. I thought that stl containers were supported in matlab, so maybe I'm doing something wrong.
The problem I have is the following:
I first retrieve the (single-precision) data as
float * someData = (float *)mxGetData(prhs[0]);
//the size below is in terms of number of components
int someDataSize = std::floor( *(float *) mxGetData(prhs[1]));
then I try to populate a vector which I initialize as
struct ThreadData {
std::vector<float> someDataVec;
}
with
someDataVec.insert(someDataVec.end(), someData, someData + someDataSize);
So to be clear: if someData is an array of 600 floats then someDataSize = 600. However, the insert (I have multiple such inserts) throws a seg-fault complaining specifically about "memmove" in "libc.so.6".
I'm currently using gcc.4.3.6, but I've also tried gcc.4.8.2 with Matlab 2014a on Red Hat. The issue persists on both compilers.
I have also tried to insert with
std::copy( someData, someData + someDataSize,
std::back_inserter(someDataVec));
and using
someDataVec.resize(someDataSize);
someDataVec.assign(someData, someData + someDataSize);
but to no avail. The exception is always the same. (Note that I have read threads making reference to a compiler flag "SECURE_SCL=0", however, I have checked mexopts.sh and this flag does not exist.) The same approach with c-style pointers (ie, float*) works without any issues.
Looking forward to your insight.
Cheers, Alvin
=============================================================================
Edit: The initialization of the structure containing the vector was incorrect. The structure is allocated in C-style (ie, using malloc as opposed to new). Resizing the vector results in an (obvious) segmentation violation.
Problem:
ThreadData * data = (ThreadData *)malloc(sizeof(ThreadData) * NUM_THREADS);
for(int i=1; i< NUM_THREADS; i++) {
data[i].someDataVec.insert( data[i].someDataVec.end(), someData, someData + someDataSize);
}
Solution:
ThreadData * data = new ThreadData[NUM_THREADS];
for(int i=1; i< NUM_THREADS; i++) {
data[i].someDataVec.insert( data[i].someDataVec.end(), someData, someData + someDataSize);
}
It is an oversight that has cost me much time.
For reference: I used electric fence to find the true violation. previous to using efence a few insertions would succeed before randomly segfaulting.

Answers (1)

James Tursa
James Tursa on 17 Mar 2015
Your post suffers from the fact that you show only partial code snippets of lines, making it impossible for the reader to know exactly what you are doing behind the (...). Based on what you have posted, I would look at this line:
int someDataSize = std::floor( *(float *) mxGetData(...));
Why would someDataSize be a function of the values in the array? Doesn't make sense to me. I would have expected something like this instead:
mwSize someDataSize = mxGetNumberOfElements(...);
  3 Comments
James Tursa
James Tursa on 17 Mar 2015
Can you put in a check to make me feel better?
if( someDataSize > mxGetNumberOfElements(prhs[0]) ) {
mexErrMsgTxt("2nd argument is greater than size of 1st argument");
}
if( !mxIsSingle(prhs[0]) ) {
mexErrMsgTxt("1st argument is not single class");
}
Alvin I
Alvin I on 17 Mar 2015
Edited: Alvin I on 17 Mar 2015
I unintentionally lied to you... See the edit above. I oversimplified the code I showed you. In fact in the test I carried the malloc'd struct array without paying attention. Apologies for this...
BUT I will put your suggested check in the code.
Thanks for the help.

Sign in to comment.

Categories

Find more on MATLAB Compiler 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!