Quantcast

Documentation Center

  • Trial Software
  • Product Updates

Memory Management

Automatic Cleanup of Temporary Arrays

When a MEX-file returns control to MATLAB®, it returns the results of its computations in the output arguments—the mxArrays contained in the left-side arguments plhs[]. MATLAB destroys any mxArray created by the MEX-file that is not in this argument list. In addition, MATLAB frees any memory that was allocated in the MEX-file using the mxCalloc, mxMalloc, or mxRealloc functions.

MathWorks® recommends that MEX-file functions destroy their own temporary arrays and free their own dynamically allocated memory. It is more efficient to perform this cleanup in the source MEX-file than to rely on the automatic mechanism. However, there are several circumstances in which the MEX-file does not reach its normal return statement.

The normal return is not reached if:

  • MATLAB calls mexErrMsgTxt.

  • MATLAB calls mexCallMATLAB and the function being called creates an error. (A source MEX-file can trap such errors by using the mexCallMATLABWithTrap function, but not all MEX-files necessarily need to trap errors.)

  • The user interrupts the binary MEX-file's execution using Ctrl+C.

  • The binary MEX-file runs out of memory. The MATLAB out-of-memory handler terminates the MEX-file.

For the first two cases, a MEX-file programmer can ensure safe cleanup of temporary arrays and memory before returning, but not in the last two cases. The automatic cleanup mechanism is necessary to prevent memory leaks in those cases.

You must use the MATLAB-provided functions, such as mxCalloc and mxFree, to manage memory. Do not use the standard C library counterparts; doing so can produce unexpected results, including program termination.

Example

This example shows how to allocate memory for variables in a MEX-file. For example, if the first input to your function (prhs[0]) is a string, in order to manipulate the string, create a buffer buf of size buflen. The following statements declare these variables:

char *buf;
int buflen;

The size of the buffer depends the number of dimensions of your input array and the size of the data in the array. This statement calculates the size of buflen:

buflen = mxGetN(prhs[0])*sizeof(mxChar)+1;

Next, allocate memory for buf:

buf = mxMalloc(buflen);

At the end of the program, if you do not return buf as a plhs output parameter, then free its memory as follows:

mxFree(buf);

Before exiting the MEX-file, destroy any temporary arrays and free any dynamically allocated memory, except if such an mxArray is returned in the output argument list, returned by mexGetVariablePtr, or used to create a structure. Also, never delete input arguments.

Use mxFree to free memory allocated by the mxCalloc, mxMalloc, or mxRealloc functions. Use mxDestroyArray to free memory allocated by the mxCreate* functions.

Persistent Arrays

You can exempt an array, or a piece of memory, from the MATLAB automatic cleanup by calling mexMakeArrayPersistent or mexMakeMemoryPersistent. However, if a MEX-file creates such persistent objects, there is a danger that a memory leak could occur if the MEX-file is cleared before the persistent object is properly destroyed. To prevent memory leaks, use the mexAtExit function to register a function to free the memory for objects created using these functions.

For example, here is a simple source MEX-file that creates a persistent array and properly disposes of it.

#include "mex.h"

static int initialized = 0;
static mxArray *persistent_array_ptr = NULL;

void cleanup(void) {
    mexPrintf("MEX-file is terminating, destroying array\n");
    mxDestroyArray(persistent_array_ptr);
}

void mexFunction(int nlhs,
    mxArray *plhs[],
    int nrhs,
    const mxArray *prhs[])
{
  if (!initialized) {
    mexPrintf("MEX-file initializing, creating array\n");
        
    /* Create persistent array and register its cleanup. */
    persistent_array_ptr = mxCreateDoubleMatrix(1, 1, mxREAL);
    mexMakeArrayPersistent(persistent_array_ptr);
    mexAtExit(cleanup);
    initialized = 1;

    /* Set the data of the array to some interesting value. */
    *mxGetPr(persistent_array_ptr) = 1.0;
  } else {
    mexPrintf("MEX-file executing; value of first array element is %g\n",
              *mxGetPr(persistent_array_ptr));
  }
}

See Also

| | |

More About

Was this topic helpful?