【问题标题】:Gracefully quit from mex file if there is a memory allocation error如果出现内存分配错误,从 mex 文件中优雅退出
【发布时间】:2012-05-16 12:51:51
【问题描述】:

我有一个 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 并给出错误消息?谢谢。

【问题讨论】:

  • 您是否尝试使用try-catch 子句?
  • float out32[totalNumElements] 如果失败,会抛出异常,不是吗?
  • @learnvst,不,分配只会导致堆栈溢出,咳咳。
  • 我在下面发布了一些解决方案。有什么方法可以检测失败的堆栈分配吗?
  • 你在栈上分配了很多内存。不要使用这个 float out32[totalNumElements];。分配动态内存。

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


【解决方案1】:

方法一

好的,一种方法是用 C-style 替换堆栈分配的变量。 . .

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

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

使用演示时出错 内存不足。

为您的选项键入 HELP MEMORY。

不需要try-catch 块或异常。

方法二

另一种方法是使用 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 网关函数中使用方法 1,在库中使用方法 2,这可能不仅仅用于制作 Matlab 扩展。这两种方法都要求您使用mxFreemxCalloc 解决方案)或deletenew 解决方案)来为in32out32 分配在堆上的内存费用。我仍然不知道如何检测或处理堆栈溢出

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-22
    • 1970-01-01
    • 2012-02-22
    • 1970-01-01
    • 2010-11-17
    • 1970-01-01
    • 2011-10-20
    • 2014-02-07
    相关资源
    最近更新 更多