Documentation

This is machine translation

Translated by Microsoft
Mouse over text to see original. Click the button below to return to the English verison of the page.

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[]. These arrays must have a temporary scope, so do not pass arrays created with the mexMakeArrayPersistent function in plhs. MATLAB destroys any mxArray created by the MEX file that is not in plhs. MATLAB also 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 MEX file 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 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?