How can I make memory persistent between calls to a MEX-file in MATLAB?
11 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
MathWorks Support Team
el 25 de Oct. de 2013
Respondida: James Tursa
el 2 de En. de 2024
I would like to know if memory allocated with mxCalloc remains persistent between calls to a MEX-file.
Respuesta aceptada
MathWorks Support Team
el 25 de Oct. de 2013
By default, in a MEX-file, mxCalloc generates non-persistent mxCalloc data. In other words, the memory management facility automatically de-allocates the memory as soon as the MEX-file ends. If you want the memory to persist after the MEX-file completes, call mexMakeMemoryPersistent after calling mxCalloc. If you write a MEX-file with persistent memory, be sure to register a mexAtExit function to free allocated memory in the event your MEX-file is cleared.
For example:
// test.c
#include <stdlib.h>
#include "mex.h"
static double *myarray = NULL;
double *pr;
void exitFcn() {
if (myarray != NULL)
mxFree(myarray);
}
void mexFunction(int nlhs,mxArray *plhs[],int nrhs, const mxArray *prhs[])
{
if (nrhs<1 | mxIsChar(prhs[0]))
mexErrMsgTxt("Must have one non-string input");
if (myarray==NULL) {
/* since myarray is initialized to NULL, we know
this is the first call of the MEX-function
after it was loaded. Therefore, we should
set up myarray and the exit function. */
/* Allocate array. Use mexMackMemoryPersistent to make the allocated memory persistent in subsequent calls*/
mexPrintf("First call to MEX-file\n");
myarray = mxCalloc(1,8);
mexMakeMemoryPersistent(myarray);
mexAtExit(exitFcn);
}
mexPrintf("Old string was '%f'.\n",myarray[0]);
pr = mxGetPr(prhs[0]);
mexPrintf("New string is '%f'.\n",pr[0]);
memcpy((char*)myarray,(char*)mxGetPr(prhs[0]), sizeof(double));
}
You can compile this MEX-file with the following command:
mex test.c
To run the MEX-file, pass in a single number. For example:
test(3)
Repetitive calls to the test MEX-file will show that the previous input is stored between calls. To clear the MEX-file from memory, use the command:
clear mex
For more information on persistent variables in MEX-files, refer to the relevent documentation by entering the following at the MATLAB prompt:
doc mexMakeArrayPersistent
and
doc mexMakeMemoryPersistent
0 comentarios
Más respuestas (1)
James Tursa
el 2 de En. de 2024
So, the accepted answer has bugs. Namely:
- They don't include the header for memcpy
- They don't check the input argument properly
Either of these can lead to a MATLAB crash if the input isn't as expected. Corrected and more robust code that doesn't rely on the messy memcpy and can correctly handle unexpected or missing input argument is:
// test.c
#include "mex.h"
static double *myarray = NULL;
void exitFcn() {
if (myarray != NULL)
mexPrintf("Free'ing the persistent memory\n");
mxFree(myarray);
}
void mexFunction(int nlhs,mxArray *plhs[],int nrhs, const mxArray *prhs[])
{
if (myarray==NULL) {
/* since myarray is initialized to NULL, we know
this is the first call of the MEX-function
after it was loaded. Therefore, we should
set up myarray and the exit function. */
/* Allocate array. Use mexMakeMemoryPersistent to make the allocated memory persistent in subsequent calls*/
mexPrintf("First call to MEX-file\n");
myarray = mxCalloc(1,8);
mexMakeMemoryPersistent(myarray);
mexAtExit(exitFcn);
}
mexPrintf("Old value was '%f'.\n",myarray[0]);
if( nrhs ) {
if (!mxIsNumeric(prhs[0]) || mxGetNumberOfElements(prhs[0]) == 0)
mexErrMsgTxt("Input must be non-empty numeric");
myarray[0] = mxGetScalar(prhs[0]);
mexPrintf("New value is '%f'.\n",myarray[0]);
}
}
0 comentarios
Ver también
Categorías
Más información sobre Write C Functions Callable from MATLAB (MEX Files) en Help Center y File Exchange.
Productos
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!