我处理这个问题的方式有没有内存问题?

时间:2014-03-01 16:12:07

标签: c++ eigen

我正在为Eigen QR写一个包装器供我个人使用,我想知道在我的实现中是否有任何内存泄漏或无证件行为,特别是在函数void get_QR(double* A, int m, int n, double*& Q, double*& R)中。答案如预期。这与我之前的问题here有关。

using std::cout;
using std::endl;
using namespace Eigen;

/*!
 Obtains the QR decomposition as A=QR, where all the matrices are in Eigen MatrixXd format.
 */
void get_QR(MatrixXd A, MatrixXd& Q, MatrixXd& R) {

        int m           =       A.rows();
        int n           =       A.cols();
        int minmn       =       min(m,n);

        //      A_E     =       Q_E*R_E.
        HouseholderQR<MatrixXd> qr(A);
        Q  =   qr.householderQ()*(MatrixXd::Identity(m, minmn));
        R  =   qr.matrixQR().block(0, 0, minmn, n).triangularView<Upper>();
}

/*!
 Obtains the QR decomposition as A=QR, where all the matrices are in double format.
 */
void get_QR(double* A, int m, int n, double*& Q, double*& R) {
        MatrixXd Q_E, R_E;
        int minmn       =       min(m,n);

        //      Maps the double to MatrixXd.
        Map<MatrixXd> A_E(A, m, n);

        get_QR(A_E, Q_E, R_E);

        Q       =       (double*)realloc(Q_E.data(), m*minmn*sizeof(double));
        R       =       (double*)realloc(R_E.data(), minmn*n*sizeof(double));
}


int main(int argc, char* argv[]) {
        srand(time(NULL));

        int m   =       atoi(argv[1]);
        int n   =       atoi(argv[2]);

//      Check the double version.
        int minmn       =       min(m,n);
        double* A       =       (double*)malloc(m*n*sizeof(double));
        double* Q       =       (double*)malloc(m*minmn*sizeof(double));
        double* R       =       (double*)malloc(minmn*n*sizeof(double));

        double RANDMAX  =       double(RAND_MAX);
        //      Initialize A as a random matrix.
        for (int index=0; index<m*n; ++index) {
                A[index]        =       rand()/RANDMAX;
        }

        get_QR(A, m, n, Q, R);
        std::cout << Q[0] << std::endl;

//      Check the MatrixXd version.
        Map<MatrixXd> A_E(A, m, n);
        MatrixXd Q_E, R_E;
        get_QR(A_E, Q_E, R_E);

        cout << Q[0] << endl;
        cout << Q_E(0,0) << endl;

        free(A);
        free(Q);
        free(R);
}

例如,我得到输出为

-0.360995
-0.360995
-0.360995

2 个答案:

答案 0 :(得分:1)

realloc不能保证与operator new[]operator delete[]兼容,只能与mallocfree兼容。

我只需用double*个对象替换所有std::vector<double>指针。

答案 1 :(得分:1)

您可以使用向量替换对malloc和free的调用。下面是如何使用带有指针加倍的现有代码的示例代码。

#include <vector>
//...
void foo(double* d, int size)
{
   d[0] = 10;
}

int main()
{
   std::vector<double> d(10);  // 10 doubles
   foo(&d[0], d.size());
}

foo()函数是一个“旧C”函数,它希望指向double的指针表示一个double数组。请注意,要做到这一点,您需要传递第一个元素的地址。

所以你的原始代码看起来像这样,如上所述:

#include <vector>
#include <algorithm>

typedef std::vector<double> VectDouble;

void get_QR(VectDouble& A, int m, int n, VectDouble& Q, VectDouble& R) 
{
    MatrixXd Q_E, R_E;
    int minmn       =       min(m,n);

    //      Maps the double to MatrixXd.
    Map<MatrixXd> A_E(&A[0], m, n);

    get_QR(A_E, Q_E, R_E);

    Q.resize(m * minmn);
    R.resize(minmn *n, 0);
}

int main(int argc, char* argv[]) 
{
    srand(time(NULL));

    int m   =       atoi(argv[1]);
    int n   =       atoi(argv[2]);

    int minmn       =       min(m,n);
    VectDouble A(m*n);
    VectDouble Q(m*minmn);
    VectDouble R(minmn*n);

    double RANDMAX  =       double(RAND_MAX);
    //      Initialize A as a random matrix.
    std::fill(A.begin(), A.end(), rand()/RANDMAX);

    get_QR(A, m, n, Q, R);
    std::cout << Q[0] << std::endl;

    Map<MatrixXd> A_E(&A[0], m, n);
    MatrixXd Q_E, R_E;
    get_QR(A_E, Q_E, R_E);

    cout << Q[0] << endl;
    cout << Q_E(0,0) << endl;
}