Path: news.mathworks.com!not-for-mail
From: <HIDDEN>
Newsgroups: comp.soft-sys.matlab
Subject: Re: Destroy Array
Date: Wed, 24 Aug 2011 13:50:15 +0000 (UTC)
Organization: Universit&#228;t Bern
Lines: 54
Message-ID: <j32vin$rcr$1@newscl01ah.mathworks.com>
References: <j2tidu$2p4$1@newscl01ah.mathworks.com> <j2tj0l$4qq$1@newscl01ah.mathworks.com> <j2tpgo$s86$1@newscl01ah.mathworks.com>
Reply-To: <HIDDEN>
NNTP-Posting-Host: www-03-blr.mathworks.com
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit
X-Trace: newscl01ah.mathworks.com 1314193815 28059 172.30.248.48 (24 Aug 2011 13:50:15 GMT)
X-Complaints-To: news@mathworks.com
NNTP-Posting-Date: Wed, 24 Aug 2011 13:50:15 +0000 (UTC)
X-Newsreader: MATLAB Central Newsreader 1490572
Xref: news.mathworks.com comp.soft-sys.matlab:741117

"James Tursa" wrote in message <j2tpgo$s86$1@newscl01ah.mathworks.com>...
> "Stiphu" wrote in message <j2tj0l$4qq$1@newscl01ah.mathworks.com>...
> > It used to work before (Matlab2010a, I use now 2011a). I made an example (which does the same thing like the code I posted above):
> > 
> > int myData[] = {1, 2, 3};
> > mxArray *prhsApp;
> > prhsApp = mxCreateDoubleMatrix(1, 3, mxREAL);
> > mxSetData(prhsApp, myData);
> > mexPutVariable("caller", "MEX_timeValues", prhsApp);
> > mxDestroyArray(prhsApp);
> > 
> > same result, Matlab crashes as soon as I call mxDestroyArray!
> 
> Both of your examples crash because you are mixing native C memory (local automatic memory or heap allocated memory) into an mxArray variable. You can't do that because when mxDestroyArray is called you will mess up the MATLAB memory manager as it will try to free the memory behind the pointer you used in the mxSetData call. The proper way to do this is to first detach your C memory from the mxArray (NULLl out the data pointer), and then call mxDestroyArray on it. E.g.,
> 
>  int myData[] = {1, 2, 3};
>  mxArray *prhsApp;
>  prhsApp = mxCreateDoubleMatrix(1, 3, mxREAL);
>  mxFree(mxGetData(prhsApp));  // Added line to avoid memory leak
>  mxSetData(prhsApp, myData);
>  mexPutVariable("caller", "MEX_timeValues", prhsApp);\
>  mxSetData(prhsApp, NULL);  // Added line to detach C native memory
>  mxDestroyArray(prhsApp);
> 
> Your listed code also has a memory leak since you overwrite the mxArray data pointer without first freeing the memory that it points to. I have added another line to correct that.
> 
> The reason you can get away with using the mixed memory mxArray in the mexPutVariable call is because this function creates a deep copy of the mxArray to put into the workspace, so no native C memory is pointed to in the actual variable that gets put in the workspace eve if there is native C memory in the original. Note that this would *not* be true if you tried to return this variable as one of the plhs[ ] array variables. If you were to try that then you would also likely crash MATLAB at some point downstream.
> 
> James Tursa

An excerpt from the Matlab example "mexgettaray.c":

	/* Since variable does not yet exist in MATLAB workspace,
           create it and place it in the global workspace. */
	array_ptr=mxCreateDoubleMatrix(1,1,mxREAL);
    }
    
    /* Increment both MATLAB and MEX counters by 1 */
    mxGetPr(array_ptr)[0]+=1;
    mex_count=(int)mxGetPr(array_ptr)[0];
    mexPrintf("%s has been called %i time(s)\n", mexFunctionName(), mex_count);
    
    /* Put variable in MATLAB global workspace */
    status=mexPutVariable("global", array_name, array_ptr);
    
    if (status==1){
	mexPrintf("Variable %s\n", array_name);
	mexErrMsgTxt("Could not put variable in global workspace.\n");
    }
    
    /* Destroy array */
    mxDestroyArray(array_ptr);

There, they don't mention the two lines you added to my code. Why?