We've been interfacing with a library created from the Matlab Compiler. Our problem is related to an array returned from the library.
Once we're finished with the array, we'd like to free the memory, however, doing this causes occasional segmentation faults.
Here is the Matlab library (bugtest.m
)::
function x = bugtest(y)
x = y.^2;
Here is the command we used to build it (creating libbugtest.so
, and libbugtest.h
)::
mcc -v -W lib:libbugtest -T link:lib bugtest.m
Here is our C test program (bug_destroyarray.c
)::
#include <stdio.h>
#include <stdlib.h>
#include "mclmcrrt.h"
#include "libbugtest.h"
#define TESTS 15000
int main(int argc, char **argv)
{
const char *opts[] = {"-nojvm", "-singleCompThread"};
mclInitializeApplication(opts, 2);
libbugtestInitialize();
mxArray *output;
mxArray *input;
double *data;
bool result;
int count;
for (count = 0; count < TESTS; count++) {
input = mxCreateDoubleMatrix(4, 1, mxREAL);
data = mxGetPr(input); data[0] = 0.5; data[1] = 0.2; data[2] = 0.2; data[3] = 0.1;
output = NULL;
result = mlfBugtest(1, &output, input);
if (result) {
/* HERE IS THE PROBLEMATIC LINE */
/*mxDestroyArray(output);*/
}
mxDestroyArray(input);
}
libbugtestTerminate();
mclTerminateApplication();
}
Here is how we compile the C program (creating bug_destroyarray
)::
mbuild -v bug_destroyarray.c libbugtest.so
We believe that mxDestroyArray(output)
is problematic.
We run the following to test crashing:
bug_destroyarray
.Roughly 10% of the time there is a crash. If this is independent across nodes then you might suppose it is crashing roughly 0.3% of the time.
When we take out that problematic line we are unable to cause it to crash.
However memory usage gradually increases when this line is not included.
From the research we've done, it seems we are not supposed to destroy the array returned, if not, how do we stop from leaking memory?
Thanks.
Okay, I know this is a little old now, but in case it helps clarify things for anyone passing by ...
Amro provides the most pertinent information, but to expand upon it, IF you don't call the mxDestroyArray
function as things stand, then you WILL leak memory, because you've set output to NULL
and so the mlf function won't try to call mxDestroyArray
. The corollary of this is that if you've called mxDestroyArray
AND then try to call the mlf function AND output
is NOT NULL, then the mlf function WILL try to call mxDestroyArray
on output
. The question then is to what does output
point? It's a bit of a dark corner what happens to output
after passing it to mxDestroyArray
. I'd say it's an unwarranted assumption that it's set to NULL
; it's certainly not documented that mxDestroyArray
sets its argument to NULL
. Therefore, I suspect what is happening is that in between your call to mxDestroyArray
and the code re-executing the mlf function, something else has been allocated the memory pointed to by output
and so your mlf function tries to free memory belonging to something else. Voila, seg fault. And of course this will only happen if that memory has been reallocated. Sometimes you'll get lucky, sometimes not.
The golden rule is if you're calling mxDestroyArray
yourself for something that is going to be re-used, set the pointer to NULL
immediately afterwards. You only really need to destroy stuff at the end of your function anyway, because you can safely re-use output variables in mlf calls.
Guy
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With