gpt4 book ai didi

c++ - mexFunction 中的内存管理问题

转载 作者:行者123 更新时间:2023-11-30 01:32:53 25 4
gpt4 key购买 nike

我正在读取一个二进制数据文件,该文件是通过调用 Matlab m 文件中的以下行编写的:

disp(sprintf('template = %d', fwrite(fid, template_1d, 'uint8')));

AFAIK, uint8 is the same size as the types BYTE, unsigned char, and unsigned short. Hence I have written the following code in a file-reading method in a C++ class instantiated in the mexfunction called by Matlab:

template1D = (unsigned short*) malloc(Nimgs*sizeof(unsigned short));printf("template1D = %d\n", fread(template1D, sizeof(unsigned short), Nimgs, dfile));

and the following is how I deallocated this member variable in the class destructor's helper function:

free((void*) template1D);

In the main mexfunction, when I did not instantiate the class object to persist in memory after mex-function completes by calling mexMakeMemoryPersistent() function, template1D gets cleared properly without segmentation error messages from Matlab. However, if I did instantiate the class to persist in memory as follows:

if (!dasani){    dasani = new NeedleUSsim;    mexMakeMemoryPersistent((void*) dasani);    mexAtExit(ExitFcn);}

with ExitFcn being:

void ExitFcn(){    delete dasani;}

then when I'm at the line of free((void*) template1D);, Matlab gives me an error message about the segmentation fault. I have checked the memory sizes and they seem to be consistent. For the malloc/calloc/free functions, I'm using Matlab's mxMalloc/mxCalloc/mxFree functions when I'm executing the C++ project as a Matlab mex function.

Based on this description, what further suggestions would you have for me to solve this problem and ensure this doesn't happen in the future (or at least know how to deal with similar problems like this in the future)?

Thanks in advance.

----------------------------Additions------------------------------------------------------

The following block of code basically shows the jists of my mex file. A mex file is basically an executable that is run in Matlab and compiled from C/C++ code with some Matlab headers.

void ExitFcn(){    delete dasani;}void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){    needle_info pin;    // check number of i/o if they are correct    if (nrhs != NUMIN)    {        mexErrMsgTxt("Invalid number of input arguments");    }    else if (nlhs != NUMOUT)    {        mexErrMsgTxt("Invalid number of output arguments");    }    // check if the input is noncomplex    if (mxIsComplex(NEEDLE))    {        mexErrMsgTxt("Input must be a noncomplex scalar integer.");    }    // check if the dimensions of the needle information is valid    int needlerows, needlecols;    needlerows = mxGetM(NEEDLE);    needlecols = mxGetN(NEEDLE);
if (needlerows < 1 || needlecols < 6)
    {        mexErrMsgTxt("Needle information's dimensions are invalid");    }    float *needlePoint, *yPoint ;    // retrieving current needle information    // order of the variables are always as follows:    // r, theta, l, rho, alpha, beta    needlePoint = (float*) mxGetData(NEEDLE) ;    pin.r = needlePoint[0];    pin.theta = needlePoint[1];    pin.l = needlePoint[2];    pin.rho = needlePoint[3];    pin.alpha = needlePoint[4];    pin.beta = needlePoint[5];    //// read the file inputs    **//if (!dasani)    //{    //  dasani = new NeedleUSsim;    //  mexMakeMemoryPersistent((void*) dasani);    //  mexAtExit(ExitFcn);    //}    dasani = new NeedleUSsim;    delete dasani;**    // sending an useless output for now (get rid of this if not conceptually needed    plhs[0] = mxCreateNumericMatrix(1,1,mxSINGLE_CLASS,mxREAL) ;    yPoint = (float*) mxGetData(plhs[0]) ;    *yPoint = 1;}

如果用户从命令行或 m 文件脚本的任何位置调用“mexfunction”,此代码将在构建/编译后运行。由“**”括起来的代码段(当我试图将代码段加粗时)是我正在查看的问题。再看一遍代码片段,我可能会在与 Matlab 内存不同的内存中为 dasani 指针分配内存(因为内存的范围仅限于 C++ mex 函数,而另一个内存空间的范围对Matlab程序)。否则,我不确定为什么 Matlab 会提示这个问题。

最佳答案

MEX API 支持 C 和 C++。因为 C 没有 try/catch 或析构函数,所以 C MEX 函数无法在发生错误时直接清理内存。因此,MATLAB 在内部列表中跟踪内存分配例程(mxMalloc、mxCalloc、mxRealloc、mxFree 和所有返回 mxArrays 的 mxCreate* 函数)的结果。如果在 MEX 函数执行期间发生错误(通过直接调用 mexErrMsgIdAndTxt,或使用 mexEvalString 之类的东西调用出错的 MATLAB 代码),则 MATLAB 将自动释放任何基于 mx 的已分配内存。但是,同样,当 MEX 函数正常终止时,MATLAB 将还释放由 MEX 函数分配的任何基于 mx 的内存。在析构函数出现之前,这对 MEX 作者来说是一种便利,但在现代 C++ 世界中它可能会变得非常烦人。

有时,就像这个问题的情况一样,您不希望 MATLAB 自动释放内存。在这种情况下,您必须对 mxArrays 使用 mexMakeMemoryPersistent 或 mexMakeArrayPersistent。

如果 mexMakeMemoryPersistent 最初是用 mxMalloc、mxCalloc 或 mxRealloc 分配的,那么你应该只传递一个指向 mexMakeMemoryPersistent 的指针。所以这段代码

dasani = new NeedleUSsim;
mexMakeMemoryPersistent((void*) dasani);

不适合大写的“B”,除非您重载了 NeedleUSsim::operator new() 以使用 mxMalloc,我不推荐这样做。但是,如果 dasani 的字段是使用 mxMalloc 等分配的,那么您希望将它们传递给 mexMakeMemoryPersistent。如果可能的话,我建议在 NeedleUSsim 构造函数中执行类似的操作,以使其靠近 mxMalloc 调用。

关于c++ - mexFunction 中的内存管理问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/907692/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com