我正在为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
答案 0 :(得分:1)
realloc
不能保证与operator new[]
和operator delete[]
兼容,只能与malloc
和free
兼容。
我只需用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;
}