Memory leak with matlab file creation??
Show older comments
Hi All, I use MATLAB 2010a and Visual2010 to create a DLL lib(I use Matrix Library API).
My problem is : when I'm tring to run my DLL throw matlab(many times), matlab display a memory error.
I suggest to post my pseudo-code of the Creation/Destruction of the matlab struct.
Create :
MainArray = mxCreateStructMatrix(1,1,0,NULL);
mxAddField(MainArray,"Field1");
mxAddField(MainArray,"Field2");
mxAddField(MainArray,"Field3");
PtrArrayField1 = mxCreateStructMatrix(1,1,0,NULL);
PtrArrayField2 = mxCreateString("Field2");
PtrArrayField3 = mxCreateNumericArray(C_NDIMS,MxDim,mxUINT32_CLASS,mxREAL);
PtrArrayTmp = mxGetField(MainArray,0,"Field2");
mxDestroyArray(PtrArrayTmp);
PtrArrayTmp = NULL;
mxSetField(MainArray,0,"Field2",PtrArrayField2);
PtrArrayTmp = mxGetField(MainArray,0,"Field3");
mxDestroyArray(PtrArrayTmp);
PtrArrayTmp = NULL;
mxSetField(MainArray,0,"Field3",PtrArrayField3);
mxAddField(PtrArrayField1 ,"SubField1");
mxAddField(PtrArrayField1 ,"SubField2");
mxAddField(PtrArrayField1 ,"SubField3");
PtrArraySubField1 = mxCreateString("SubField1");
PtrArraySubField2 = mxCreateString("SubField2");
PtrArraySubField3 = mxCreateString("SubField3");
PtrArrayTmp = mxGetField(PtrArrayField1,0,"SubField1");
mxDestroyArray(PtrArrayTmp);
PtrArrayTmp = NULL;
PtrArrayTmp = mxGetField(PtrArrayField1,0,"SubField2");
mxDestroyArray(PtrArrayTmp);
PtrArrayTmp = NULL;
PtrArrayTmp = mxGetField(PtrArrayField1,0,"SubField3");
mxDestroyArray(PtrArrayTmp);
PtrArrayTmp = NULL;
mxSetField(PtrArrayField1,0,"SubField1",PtrArraySubField1);
mxSetField(PtrArrayField1,0,"SubField2",PtrArraySubField2);
mxSetField(PtrArrayField1,0,"SubField3",PtrArraySubField3);
PtrArrayTmp = mxGetField(MainArray,0,"Field1");
mxDestroyArray(PtrArrayTmp);
PtrArrayTmp = NULL;
mxSetField(MainArray,0,"Field1",PtrArrayField1);
///////////////////////////////////////////////////////// /*End Creation*/ /////////////////////////////////////////////////////////
Destroy :
PtrArrayField = mxGetField(MainArray,0,"Field2");
mxSetField(MainArray,0,"Field2",NULL);
mxDestroyArray(PtrArrayField);
PtrArrayField = NULL;
PtrArrayField = mxGetField(MainArray,0,"Field3");
mxSetField(MainArray,0,"Field3",NULL);
mxDestroyArray(PtrArrayField);
PtrArrayField = NULL;
PtrArrayField = mxGetField(MainArray,0,"Field1");
PtrArraySubField = mxGetField(PtrArrayField,0,"SubField1");
mxSetField(PtrArrayField,0,"SubField1",NULL);
mxDestroyArray(PtrArraySubField);
PtrArraySubField = NULL;
PtrArraySubField = mxGetField(PtrArrayField,0,"SubField2");
mxSetField(PtrArrayField,0,"SubField2",NULL);
mxDestroyArray(PtrArraySubField);
PtrArraySubField = NULL;
PtrArraySubField = mxGetField(PtrArrayField,0,"SubField3");
mxSetField(PtrArrayField,0,"SubField3",NULL);
mxDestroyArray(PtrArraySubField);
PtrArraySubField = NULL;
mxSetField(MainArray,0,"Field1",NULL);
mxDestroyArray(PtrArrayField);
PtrArrayField = NULL;
///////////////////////////////////////////////////////// /*End Destroy*/ /////////////////////////////////////////////////////////
thank you for your help.
Answers (1)
Geoff Hayes
on 13 Oct 2014
0 votes
Abdellatif - for every mxCreate... that creates an mxArray you need to call mxDestroyArray on that array. You will need to rework your code so that you always pair up a create with a destroy (once finished with the array that was allocated memory via the create function).
10 Comments
abdellatif amar
on 13 Oct 2014
Geoff Hayes
on 13 Oct 2014
Take a look at
PtrArrayField2 = mxCreateString("Field2");
Where do you free the memory allocated to PtrArrayField2? Same with
MainArray = mxCreateStructMatrix(1,1,0,NULL);
There is no corresponding line in your pseudocode that indicates that you are freeing memory that was allocated to this mxArray structure.
abdellatif amar
on 13 Oct 2014
Edited: James Tursa
on 17 Oct 2014
Geoff Hayes
on 13 Oct 2014
How? PtrArrayField is not PtrArrayField2..
abdellatif amar
on 13 Oct 2014
Geoff Hayes
on 14 Oct 2014
I don't think it is the same. Note that you do the following
PtrArrayField1 = mxCreateStructMatrix(1,1,0,NULL);
PtrArrayField2 = mxCreateString("Field2");
PtrArrayField3 = mxCreateNumericArray(C_NDIMS,MxDim,mxUINT32_CLASS,mxREAL);
So you create three different mxArrays, but at no time do you free memory for any. And PtrArrayField is just a field returned by mxGetField. Now note the comment from mxGetField:
Do not call mxDestroyArray on an mxArray returned by the mxGetField function.
Destroy calls should only be paired with create function calls.
abdellatif amar
on 14 Oct 2014
Geoff Hayes
on 14 Oct 2014
The code (which you haven't posted) may do that, but the pseudo-code does not. And from the MATLAB documentation, you are not supposed to be calling mxDestroyArray on an mxArray returned by the mxGetField function...which is exactly what your pseudo-code is showing.
abdellatif amar
on 14 Oct 2014
Geoff Hayes
on 14 Oct 2014
That pseudo-code seems a little complicated, especially for the struct destruction. Reviewing the documentation indicates that you would only do what you have shown (above) for changing the field. For the other, To free memory for structures created using this function, call mxDestroyArray only on the structure array. Do not call mxDestroyArray on the array pvalue points to. If you do, MATLAB® attempts to free the same memory twice, which can corrupt memory.
I think then that you could do something like the following
#include "mex.h"
#include <string.h>
#define NUMBER_OF_STRUCTS 1
#define NUMBER_OF_FIELDS 1
void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
{
const char* pFieldNames[] = {"Field2"};
mwSize dims[2] = {1, NUMBER_OF_STRUCTS};
// create the struct array
mxArray* pStructArray = mxCreateStructArray(2,dims,
NUMBER_OF_FIELDS, pFieldNames);
// create the field value
mxArray* pArrayField2 = mxCreateString("this is my string value");
// set the field
mxSetField(pStructArray,0,"Field2",pArrayField2);
// do modification
// free memory allocated to current value
mxDestroyArray(pArrayField2);
// create the new string value
pArrayField2 = mxCreateString("this is my other string value");
// update the field
mxSetField(pStructArray,0,"Field2",pArrayField2);
// free memory from struct
mxDestroyArray(pStructArray);
}
Categories
Find more on Write C Functions Callable from MATLAB (MEX Files) 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!