如果存在内存分配错误,请从mex文件中正常退出

时间:2012-05-16 12:51:51

标签: c++ matlab exception memory-management mex

我有一个mex函数,它采用双精度输入向量,将精度向下转换为临时单精度向量,进行一些处理,然后再将处理结果向上转换为双倍精度。

以下简化代码示例编译并说明了此过程。

#include "mex.h"

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{           
  int xM = mxGetM(prhs[0]); 
  int xN = mxGetN(prhs[0]);         
  int totalNumElements = xM*xN;       

  plhs[0] = mxCreateDoubleMatrix(xM,xN,mxREAL);

  double* out  = mxGetPr(plhs[0]); 
  double* in   = mxGetPr(prhs[0]);    

  float out32[totalNumElements]; 
  float  in32[totalNumElements]; 

  // ---------> DOWNCAST <---------
  for (int mm = 0; mm < totalNumElements; ++mm)
      in32[mm] = (float)in[mm];
  // ---------- DOWNCAST ----------

  // Do some single precision signal processing (just copy for this example)
  for (int mm = 0; mm < totalNumElements; ++mm)
      out32[mm] = in32[mm];

  // ---------> UPCAST <---------
  for (int mm = 0; mm < totalNumElements; ++mm)
      out[mm] = (double)out32[mm];
  // ---------- UPCAST ---------- 
}

在我的机器上,调用这样编译的mex函数可以正常工作。 。

>> x = randn(1e6,1); y=demo(x);

...但是这样调用会导致Matlab意外关闭

>> x = randn(1e7,1); y=demo(x);

看到崩溃是由输入向量的大小增加引起的,我猜这个错误是由于内存分配失败引起的。如果出现这样的错误,我如何优雅地退出Matlab给出错误消息?感谢。

1 个答案:

答案 0 :(得分:2)

方法1

好的,一种方法是用C风格替换堆栈分配的变量。 。

 float*  in32  =  (float*)mxCalloc(totalNumElements, sizeof(float));
 float*  out32 =  (float*)mxCalloc(totalNumElements, sizeof(float));

当出现内存错误时,Matlab会巧妙地给出以下错误。 。

  

使用demo内存不足时出错。

     

键入HELP MEMORY以获取选项。

无需try-catch个阻止或例外。

方法2

另一种方法是使用C ++样式std::exception。堆栈分配的变量可以替换为以下...

  float*  in32;
  float*  out32;
  try
  {
      in32  = new float[totalNumElements];
      out32 = new float[totalNumElements];
  }
  catch (std::exception& e)
  {
      std::string msg = std::string("Aw snap: ") + e.what();
      mexErrMsgTxt(msg.c_str());
  }

当出现内存错误时,Matlab会巧妙地给出以下错误。 。

  

使用演示

时出错      

Aw snap:std :: bad_alloc

备注

方法1更紧凑,更好地与mex API集成。最好在库中的mex网关函数和方法2中使用方法1,这可能只是在进行Matlab扩展时使用。这两种方法都要求您使用mxFreemxCalloc解决方案)或deletenew解决方案),以便为in32的堆上分配的内存付费和out32。我仍然不知道如何检测或处理堆栈溢出