MATLAB Answers

do not understand mxSetData

5 views (last 30 days)
gujax
gujax on 8 Mar 2012
Hi, I have declared a pointer to a float
float *myvariable;
I initialize this to
myvariable = mxCreateNumericMatrix(256,1,SINGLE (sorry for not the exact syntax),0);
Then I call a function func(myvariable);
This function does math on myvariable and returns the pointer.
Now if I have to output this variable, I get Matlab crash with this:
mxSetData(plhs[0],(float*)myvariable);
I have tried mxFree before the line but still a problem.
Questions: 1. If the second parameter is void according to definition how come my program compiles fine without error.
2. Why does Matlab crash (implying memory leak)?
3. The other option works and this is
plhs[0] = mxCreateNumericArray(256 matrix of SINGLE 0) and finally myvariable=mxGetData(plhs[0]); func(myvariable);
The reason I do not like this way is
a. I would prefer to run the function first and then assign the return to plhs[0];
b. It is a very ugly way of doing it like this, though it works.
c. I would at some point like to declare "myvariable" to be static so that every time it is requested by Matlab function some.m, I do not initialize it to 0. And I have many such variables to work with. I am updating data every fraction of a second for several minutes.
And I have to work with floats
Thanks

  0 Comments

Sign in to comment.

Accepted Answer

Jan
Jan on 8 Mar 2012
mxCreateNumericMatrix creates a Matlab variable and returns a mxArray * pointer to it. This variable has a header, e.g. the type of the values, and contains a pointer to the actual data, see mxGetPr for a DOUBLE array or mxGetData for all other types.
mxSetData injects a pointer to the data manually to the Matlab variable. This overwrites the pointer to the existing values. If you assign an mxArray pointer to the data, a crash is expected.
You have to distinguish between the Matlab arrays and their data:
float *data;
plhs[0] = mxCreateNumericMatrix(...);
data = (float *) mxGetData(plhs[0]);
func(data);
I prefer to use Matlab arrays in the main function (mexFunction) only and call all subfunctions using the C-pointers to the underlying data. Then the mexFunction is the gateway between Matlab and C and it is easy to use the subfunctions in a pure C program also.

  13 Comments

gujax
gujax on 9 Mar 2012
Thank you all for suggestions and I have followed your advice - i.e., not play with mxSetData (though I am curious to know where it can be used. I see no examples anywhere).
I have something off from an old answer by James Tursa which prompted me to do exactly what he suggested - but my program crashed despite it.
I am not blaming James - it is likely that I must have additionally done something wrong (I was - I was not initializing plhs but neither do I see James doing it in his solution). I am just saying that his old answer to someone else's similar problem provided me with a solution - which did not work unfortunately for me and that is what prompted my question and you know the rest.
So here it is just for the sake of completion.
Re: Copying array from my DLL into mxCreateNumericArray pointer
Posted: Jan 23, 2009 2:24 PM
Ashish has already solved your problem, but I would like to point out what is wrong with your code, particularly the mxSetData calls. Here is your code snippet:
long* imageArray = 0;
unsigned int returnCode = 0;
:
imageArray = (long*)mxMalloc(arrayLength * sizeof(long));
:
returnCode = MyFunction(imageArray, arrayLength);
:
mxSetData(plhs[0], &returnCode);
mxSetData(plhs[1], &imageArray);
returnCode is a local variable, it no longer exists once mexFunction returns to MATLAB. So you can't use its memory in an mxArray. You can only use memory created with the mx___ functions in mxArray variables. What you have done will certainly access invalid memory once the mexFunction exits, possibly resulting in a seg fault at some point, because the data pointer for the return variable plhs[0] will no longer be valid once the mexFunction exits.
imageArray is already a pointer to a data area created with an mx___ function, so you are in good shape here. You just need to pass this value as the second argument. But what you have done is pass the address of the imageArray variable itself, not the address of the data it points to. This will corrupt memory. You should have done this:
mxSetData(plhs[1], imageArray);
And finally, you should be aware that mxSetData does NOT free the existing data memory before setting the new pointer values. Even if you had coded the mxSetData calls correctly, it would have resulted in a memory leak. mxSetData calls should be set up like this:
mxFree(mxGetData(plhs[0]));
mxSetData(plhs[0], whatever);
mxFree(mxGetData(plhs[1]));
mxSetData(plhs[1], whatever);
Leaking memory created with mx___ calls is garbage collected by MATLAB when mexFunction exits so usually this won't be a serious problem, but it is still bad programming practice.
Having said all that, I would again point you to Ashish's response, which contains a much better way of accomplishing your goals without resorting to mxSetData.
James Tursa
gujax
gujax on 9 Mar 2012
correction: Actually, I happened across James old suggestion after I had placed in my query. But I noticed that I did what was being suggested.
Also if my response sounds offending please let me know and I will delete it. I am not pointing blame at James and I must emphatically state that I had made a mistake in not initializing plhs. Once I initialize, the above code by James works fine and no more crashes - though my new code only uses mxGetData. I have shied away from setData and its ghosts. And yes - I barely program in C.
gujax
James Tursa
James Tursa on 10 Mar 2012
@gujax: I am never offended in the least by someone pointing out my mistakes. That is how I learn, and I like to learn. Thanks for your gracious regard for my feelings, but it is really not necessary in my case. Post anything you want. (It would not surprise me that I have some errors in my oldest posts)
Regarding what will or will not work in your case, I would suggest you post your code as you currently have it and then we can comment on it. There are subtleties of creating mxArray variables from pieces that are *not* in the documentation ... I simply had to learn them from other posters (e.g. Jan, Bruno, Walter, et al) or from trial and error on my own part. Using the mxCreateETC functions are hard enough for a beginning mex programmer to deal with without venturing into the mxSetData etc stuff, hence the wise advice from Jan to avoid it if you can ... at least for now. But post your code and we can go from there.

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!

Translated by