【问题标题】:Mex class memory leak - Is a destructor needed with STL maps?Mex 类内存泄漏 - STL 映射是否需要析构函数?
【发布时间】:2013-02-07 01:51:28
【问题描述】:

我正在寻找一些 mex 代码中的内存泄漏(我工作的 IT 支持没有安装有用的调试标志,使得 Valgrind 几乎没用......)。

我发现的一个潜在来源是我自制的 Matrix 课程。它使用映射的 STL 映射(即 map<int, map<int, double> > 来存储矩阵。我曾假设由于我使用了 STL,C++ 可以在程序执行结束时自动处理垃圾收集,但我现在想知道,我是否需要对析构函数进行硬编码以先清除内部映射,然后再清除外部映射?

唯一的其他实例变量是几个整数,所以我看不出它们会导致任何问题。

为清楚起见,Matrix 类定义的相关部分:

class Matrix
{
    public:
        std::map< int, std::map<int, double> > elems;
        int rows;
        int cols;

        Matrix( );
        Matrix( int numRows, int numCols );

        // ... Getters, setters, operations and other miscellanea
}

(我意识到将我的实例变量声明为 public 是草率的 OO 实践,但这对你来说是 hacky 研究代码!)。

如果不是析构函数,我想知道它是否在以下代码中:

    Matrix D;
    distance_cost( &D, &traj1, &traj2 ); // Init Matrix and flesh out data
    plhs[1] = mxCreateDoubleMatrix( D.rows, D.cols, mxREAL ); // Prepare output
    D_output = mxGetPr( plhs[1] );
    D.toDouble( D_output ); // Convert Matrix data maps to double* for Matlab

distance_cost 是这样定义的:

void distance_cost( Matrix *Q, Trajectory *A, Trajectory *B) {

    int M = A->length( );
    int N = B->length( );

    (*Q) = Matrix( M, N );

    for( int m=0; m < M; m++ ) {
        for( int n=0; n < N; n++ ) {
            float dist = A->at(m).dist2D( B->at(n) );
            Q->set(m,n,dist);
        }
    }

}

而toDouble() 是:

void Matrix::toDouble( double *dbl ) const {
    for( int i=0; i < this->rows; i++ ) {
        for( int j=0; j < this->cols; j++ ) {
            dbl[i+j*this->rows] = this->at(i,j);
        }
    }
}

欢迎任何关于我草率使用内存管理的帮助、建议或批评 - 我已经把自己深深地陷进了泥潭,无法真正弄清楚如何摆脱它!

【问题讨论】:

  • 如何知道 MEX 文件正在泄漏内存? MEX 文件中是否有任何全局变量?此外,distance_cost 确实应该引用这些参数而不是指针。 Q 应该是Matrix&amp;,而另外两个应该是Trajectory const&amp;。
  • 不,你不需要做任何事情,编译器会自动生成所有的析构函数调用
  • @Praetorian,当我从代码中注释掉对该 mex 函数的调用时,我的内存使用量保持相当稳定(我用一些空白矩阵替换了输出以进行检查)。如果启用,我会烧毁内存,然后页面文件然后 Matlab 死掉......(它被调用了几十万次)。
  • @aleguna,谢谢,这就是我的假设。
  • 您确定要将输出矩阵分配给plhs[1] 而不是plhs[0];尽管 MATLAB 具有基于 1 的索引,但您在 MEX 文件中编写 C 或 C++,因此索引是基于 0 的。此外,您关于将数据转换为 MATLAB 的 double * 的评论很烦人。 mxGetPr 将real_T * 返回到您通过mxCreateDoubleMatrix 调用分配的内存。这个内存区域的大小是rows * cols。您应该只将数据从 Matrix 类复制到该区域,而不是分配任何东西。请记住,MATALB 期望矩阵以列为主。

标签: c++ matlab memory-leaks destructor mex


【解决方案1】:

如果这些都是Matrix中的所有成员变量,那么你很可能没问题。

  • std::map&lt; int, std::map&lt;int, double&gt; &gt; elems;
  • int rows;
  • int cols;

某个特定的函数总是有可能泄漏内存。但从您向我们展示的内容来看,您不会泄漏任何内存。

【讨论】:

  • 是的,谢谢 - 我也这么想,但我越来越绝望了!
  • 关于您的编辑,我认为您不应该为任何用作输出的数组调用destroy array。它在此处的项目符号列表中:mathworks.co.uk/help/matlab/matlab_external/… 除非我误解了它?
  • 不,他不需要打电话给mxDestroyArray!矩阵是 MEX 文件的输出参数,MATLAB 会负责销毁它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-28
  • 1970-01-01
  • 2011-03-22
  • 2013-11-28
相关资源
最近更新 更多