MEX-файлы загружаются в память при первом вызове.В этот момент глобальные переменные в MEX-файле получают место в памяти и инициализируются.Далее вызывается mexFunction
, где ваш код получает возможность выделить память и назначить указатель на эту глобальную переменную.
При следующем вызове MEX-файла он все еще загружается в память, и этиглобальные переменные все еще там.На этот раз MATLAB просто нужно вызвать mexFunction
.
Когда вы выполните clear mex
или clear all
в MATLAB, MEX-файл будет выгружен из памяти.Глобальные переменные перестанут существовать в этой точке.Поскольку вы использовали mxCalloc
для выделения памяти, MATLAB может вернуть потерянную память.Если бы вы использовали calloc
вместо этого, вы бы потеряли память в этот момент.
При следующем вызове MEX-файла это будет так же, как при первом вызове.
Обратите внимание, что, поскольку MEX-файл является скомпилированным двоичным файлом, имена ваших переменных больше не отображаются (за исключением информации отладки).Машинный код имеет дело только с адресами и регистрами памяти.
В случае C ++ правила области видимости, наследование и т. Д. - это всего лишь абстракции, которые приводят к тому же машинному коду, который вы можете получить с помощью C или любого другого скомпилированного языка..
Несколько случаев, чтобы прояснить ситуацию:
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
static int* myVar = NULL; // This is basically the same as a global myVar in this case
if(myVar == NULL)
{
myVar = (int*)mxCalloc(sizeof(int*), 10);
//mexMakeMemoryPersistent(myVar); // Let's leave out this line!
myVar[0] = 1;
}
myVar[0] *= 2;
}
В вышеописанном случае мы не делали память постоянной.Указатель myVar
сохраняется при вызовах MEX-файла, но не указывается в памяти.Во второй раз, когда вы вызываете MEX-файл, myVar[0] *= 2
сделает что-то недопустимое и, вероятно, приведет к сбою MATLAB.
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
int* myVar = NULL; // This is now a local variable
if(myVar == NULL)
{
myVar = (int*)mxCalloc(sizeof(int*), 10);
mexMakeMemoryPersistent(myVar);
myVar[0] = 1;
}
myVar[0] *= 2;
}
В приведенном выше случае myVar
будет иметь значение NULL при каждом вызове MEX-файла, так что каждый раз будет выделяться новая память.Память постоянна, поэтому в конечном итоге вам не хватит памяти с этим.
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
static int* myVar = NULL;
if(myVar == NULL)
{
myVar = (int*)malloc(sizeof(int*), 10); // Using the system malloc
myVar[0] = 1;
}
myVar[0] *= 2;
}
В приведенном выше случае все в порядке, за исключением того, что память, выделенная malloc
, никогда не освобождается.Когда вы выполните clear all
или clear mex
, MEX-файл будет очищен, статическая переменная myVar
будет удалена, но память, выделенная malloc
, все еще там.Вы снова теряете память.Если вы хотите сделать это таким образом, вам нужно зарегистрировать функцию, которая будет запускаться, когда MEX-файл существует, используя mexAtExit()
.
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
static int myVar[10] = {1};
myVar[0] *= 2;
}
В приведенном выше случае мы используем статическую переменную дляхранить все наши данные, динамическое распределение памяти не используется, нам не нужно беспокоиться об утечке памяти.Я рекомендую это, если массив не очень большой.