How can I make memory persistent between calls to a MEX-file in MATLAB?
12 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
MathWorks Support Team
le 25 Oct 2013
Réponse apportée : James Tursa
le 2 Jan 2024
I would like to know if memory allocated with mxCalloc remains persistent between calls to a MEX-file.
Réponse acceptée
MathWorks Support Team
le 25 Oct 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 commentaires
Plus de réponses (1)
James Tursa
le 2 Jan 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 commentaires
Voir également
Catégories
En savoir plus sur Write C Functions Callable from MATLAB (MEX Files) dans Help Center et File Exchange
Produits
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!