Drexel dragonThe Math ForumDonate to the Math Forum



Search All of the Math Forum:

Views expressed in these public forums are not endorsed by Drexel University or The Math Forum.


Math Forum » Discussions » Software » comp.soft-sys.matlab

Topic: matlab/mex function doesn't free memory
Replies: 22   Last Post: Dec 10, 2012 1:49 AM

Advanced Search

Back to Topic List Back to Topic List Jump to Tree View Jump to Tree View   Messages: [ Previous | Next ]
James Tursa

Posts: 2,069
Registered: 8/5/09
Re: matlab/mex function doesn't free memory
Posted: Dec 5, 2012 3:36 PM
  Click to see the message monospaced in plain text Plain Text   Click to reply to this topic Reply

"Xueming " <emilyhexueming@hotmail.com> wrote in message <k9n94g$gtu$1@newscl01ah.mathworks.com>...
>
> Hi James,
> Now I have two issues,
> 1) I create a C function, which will be called by Matlab, and when everytime it's called, it create a mxArray and return this pointer to Matlab. With called more and more times, it creates more and more mxArray. I guess the memory must be significantly occupied. I'm thinking if we can mxDestory a mxArray (by writing another function) as soon as it's returned to Matlab, so that we only allocate memory for current mxArray.


I'm not really sure what you are doing with (1) above, so can't comment. If you show the associated code then I could comment.

> 2)How about inside C code, if declaring a global mxArray*, how to make this global pointer point to a mxArray which is returned by a C function.
> I tried to declare a global mxArray*, and set it point to a mxArray and returned to Matlab. This global mxArray* is used in other functions. But it seems in other functions, the global mxArray pointer could not be found where it points to. I got some strange result. Could anyone tell me the reason. Here is a simple code.
> if run this code, calllib('mxArrayTest', 'create'), calllib('mxArrayTest','test'); the result of retruing mxCell1 and mxCell_g are completely different. The free_mxelem(mxCell_g) works pretty well just following mxCell_g=mxCell1, however, outside the "create" function, the free_mxelem() shows pretty strange result. I assume this is because after C returns mxArray to Matlab, memory of mxArray will be free automatically.


For (2) above, it appears from your code that you have a fundamental misunderstanding of how garbage collection works with API function calls. All of the official API functions for creating mxArray variables (i.e., the mxCreateEtc functions) put the address of the created mxArray on the garbage collection list, which I will call the Variable Array List (VAL) for lack of a better term. When the mex function or calllib function returns control back to the caller (i.e., MATLAB), everything on the VAL is destroyed. It appears that that is what is going on in your code. To make a mxArray persist and not be garbage collected between calls, you must remove its address from the VAL prior to the function exiting and returning control back to the caller. The function for this is mexMakeArrayPersistent. E.g., in this code snippet:

> mxCell1=mxCreateCellMatrix(1,2);
> mxSetCell(mxCell1,0,mxCell);
> mxSetCell(mxCell1,1,mxString);
>
> mxCell_g=mxCell1;


Your mxCell_g is your global mxArray that you want to persist between calls. So you need to follow up the above code with this line which will remove mxCell_g from the VAL:

mexMakeArrayPersistent(mxCell_g);

CAUTION: Once you make the above call, mxCell_g is permanently removed from the VAL and there is no way to get it back on the VAL that I know of. So you risk a permanent memory leak if you don't have adequate code in place to destroy this mxArray. E.g., a function within the library to destroy this mxArray (so you can destroy it manually), and code in place that detects when the library is being detached from MATLAB (e.g., unloaded from memory) so that it can destroy the mxArray prior to being unloaded. Etc.

(btw, There is a similar function, mexMakeMemoryPersistent, for raw memory allocated with mxMalloc and friends that removes it from garbage collection. In that case, there *is* an undocumented function to get it back on the garbage collection list.)

Another suggestion I will make is to keep your global pointers in a valid state at all times. E.g., do this declaration instead of the one you have:

mxArray *mxCell_g = NULL;

That way it starts in a testable state indicating there is no variable present. When you create a variable, always test mxCell_g first, and if it is not NULL then destroy it before replacing it with another allocated mxArray. And whenever you destroy the variable in mxCell_g, set mxCell_g = NULL. Etc. That way you can always test the value of mxCell_g anywhere in your code to determine its state and if there is a variable present.

Also, I would note that the following code:

> str=(char*)malloc(sizeof(char)*20);
> strcpy(str,"mxArray Test");
> mxString=mxCreateString(str);


can be replaced with this simpler line:

mxString=mxCreateString("mxArray Test");

The code you have is cumbersome and leaks the memory behind the str pointer.

James Tursa



Point your RSS reader here for a feed of the latest messages in this topic.

[Privacy Policy] [Terms of Use]

© Drexel University 1994-2014. All Rights Reserved.
The Math Forum is a research and educational enterprise of the Drexel University School of Education.