"James Tursa" wrote in message <firstname.lastname@example.org>... > "Xueming " <email@example.com> wrote in message <firstname.lastname@example.org>... > > > > 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 James,hank you very much for pointing out my misunderstanding of garbage collection mechanism, and my careless about pointer initialization. I found the memory management issues on Mathwork website, and gonna take a look very carefully. Btw, I tried to put mexMakeArrayPersistent(mxCell_g); following mxSetCell(mxCell1,1,mxString); mxCell_g=mxCell1; but it did work. I was wondering since there is a cell in mxCell1, should I keep it from being destroyed as well?