Memory leak with matlab file creation??

조회 수: 4 (최근 30일)
abdellatif amar
abdellatif amar 2014년 10월 13일
편집: James Tursa 2014년 10월 17일
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.

답변 (1개)

Geoff Hayes
Geoff Hayes 2014년 10월 13일
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
abdellatif amar
abdellatif amar 2014년 10월 14일
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 2014년 10월 14일
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);
}

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 C Shared Library Integration에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by