Memory leak with matlab file creation??

3 views (last 30 days)
abdellatif amar
abdellatif amar on 13 Oct 2014
Edited: James Tursa on 17 Oct 2014
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
Geoff Hayes on 13 Oct 2014
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
abdellatif amar on 14 Oct 2014
You are right, But according to the documentation of mxSetField : Use the mxGetField function to get a pointer to the field, call mxDestroyArray on the pointer, then call mxSetField to assign the new value. and this is what i am doing in my pseudo-code:
for the struct creation :
PtrArrayField2 = mxCreateString("Field2");
PtrArrayTmp = mxGetField(MainArray,0,"Field2");
mxDestroyArray(PtrArrayTmp);
PtrArrayTmp = NULL;
mxSetField(MainArray,0,"Field2",PtrArrayField2);
for the struct destruction:
PtrArrayField = mxGetField(MainArray,0,"Field2");
mxSetField(MainArray,0,"Field2",NULL);
mxDestroyArray(PtrArrayField);
PtrArrayField = NULL;
Geoff Hayes
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);
}

Sign in to comment.

Categories

Find more on Data Types 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!