1

I have a mex code where the output variable has the same name as the input variable, but it changes size as a result of the operations of the mex code. For instance, I have something like:

A=Function(A) where A in the input is a 100 X 1 vector (much much larger in my simulation) and the output A is a 50 X 1 vector. I want to understand how memory is managed in this situation. After the operation is finished, does A now occupy 50 X 1 worth of space and the rest is free to allocate to other variables?

Thanks!

Siddharth

  • 1
    Very interesting question. I had thought I knew the answer, but in the process of answering the question, I actually learned some interesting and unexpected things about how this is handled. – chappjc Jan 23 '15 at 23:26
  • Also have a look at my answer [here](http://stackoverflow.com/a/19850676/2778484) where I looked at the shared copy mechanism. – chappjc Jan 26 '15 at 21:22

1 Answers1

2

That is correct, the data buffer for the original A is destroyed by MATLAB and a new buffer is created (the same mxArray structure address is reused presumably by copying the new one onto the original after deallocating the original array's data buffer). This is assuming you are not writing to prhs[i] in you MEX file!

You can see this with format debug. You will observed that the output mxArray has the same address, but it's data buffer has a different address, so it has clearly reallocated the output array. This suggests that the original buffer is deallocated or queued to be deallocated.

Starting with the output for a change, of the file testMEX.mexw64 that takes the first half of the input array's first row and copies it into a new array:

>> format debug
>> A = rand(1,8)
A =

Structure address = efbb890
m = 1
n = 8
pr = 77bb6c40
pi = 0
    0.2581    0.4087    0.5949    0.2622    0.6028    0.7112    0.2217    0.1174
>> A = testMEX(A)
A =

Structure address = efbb890
m = 1
n = 4
pr = 77c80380
pi = 0
    0.2581    0.4087    0.5949    0.2622

Note that pr is different, meaning that MATLAB has created a new data buffer. However, the mxArray "Structure address" is the same. So, at the minimum, the old data buffer will be deallocated. Whether or not the original mxArray structure is simply mutated or a new mxArray is created is another question (see below).


Edit: The following is some evidence to suggest that an entirely new mxArray is created and it is copied onto the old mxArray

Add the following two lines to the MEX function:

mexPrintf("prhs[0] = %X, mxGetPr = %X, value = %lf\n", 
    prhs[0], mxGetPr(prhs[0]), *mxGetPr(prhs[0]));
mexPrintf("plhs[0] = %X, mxGetPr = %X, value = %lf\n", 
    plhs[0], mxGetPr(plhs[0]), *mxGetPr(plhs[0]));

The result is:

prhs[0] = EFBB890, mxGetPr = 6546D840, value = 0.258065
plhs[0] = EFA2DA0, mxGetPr = 77B65660, value = 0.258065

Clearly there is a temporary mxArray at EFA2DA0 containing the output (plhs[0]), and this mxArray header/structure is entirely copied onto the old mxArray structure (the one as A in the base MATLAB workspace). Before this copy happens, MATLAB surely deallocates the data buffer at 6546D840.

testMEX.cpp

#include "mex.h"

void mexFunction(int nlhs, mxArray *plhs[],  int nrhs, const mxArray *prhs[])
{
    mxAssert(nrhs == 1 && mxGetM(prhs[0]) == 1, "Input must be a row vector.");
    double *A = mxGetPr(prhs[0]);
    size_t cols = mxGetN(prhs[0]);
    size_t newCols = cols / 2;

    plhs[0] = mxCreateDoubleMatrix(1, newCols, mxREAL);

    for (int i = 0; i < newCols; ++i)
        mxGetPr(plhs[0])[i] = A[i];

    mexPrintf("prhs[0] = %X, mxGetPr = %X, value = %lf\n", 
        prhs[0], mxGetPr(prhs[0]), *mxGetPr(prhs[0]));
    mexPrintf("plhs[0] = %X, mxGetPr = %X, value = %lf\n", 
        plhs[0], mxGetPr(plhs[0]), *mxGetPr(plhs[0]));

}
chappjc
  • 30,359
  • 6
  • 75
  • 132