C ++指向Eigen :: Map <eigen :: vectorxd>对象的特征指针

时间:2017-09-05 17:27:50

标签: c++ pointers eigen dynamic-allocation

是否可以定义指向Eigen :: Map对象的指针?原始代码非常复杂,但这是我想要实现的(伪代码)

void testfunction1(... XPtr){
  // XPtr is a pointer
  // create a vector, map it to a Map object and make XPtr point to the latter

  VectorXd Xnew(9);
  Xnew <<  10, 20, 30, 40, 50, 60, 70, 80, 90;
  Map<VectorXd> XnewMap(Xnew.data(), 9); 

  // make XPtr point to XnewMap so that Xnew data can be 
  // accessed outside testfunction1()
  // ... how? I suspect this to involve some dynamic memory allocation
};

void testfunction2(bool yes){
  // main function

  VectorXd XR(9);
  XR <<  1, 2, 3, 4, 5, 6, 7, 8, 9;
  const Map<VectorXd> X(XR.data(), 9); // yes the mapped version is needed

  // create a pointer to X, say XPtr
  // ... how?

  if(yes){ // make XPtr point to XnewMap which is defined in testfunction1()
     testfunction1(XPtr);
   };

  //... some computations

  // make XPtr point again to X
  // ... how?

};

1 个答案:

答案 0 :(得分:1)

首先不需要在这里使用指针,因为Map本质上已经是一个指针,所以它会更简单,所以用placement new更新Map对象。尽管如此,您的当前设计需要在testfunction1中进行分配,并在testfunction2中进行解除分配,以防它被分配,这不是很安全。因此,通过在函数(或命名的lambda)中放入“一些计算”来更好地采用功能设计,使testfunction1按值返回:

VectorXd testFunction1() { return Xnew; }

void testfunction2(bool yes){
  VectorXd XR(9);
  XR <<  1, 2, 3, 4, 5, 6, 7, 8, 9;
  const Map<VectorXd> X(XR.data(), 9);

  auto func = [&] (Eigen::Ref<VectorXd> X) {
    /* some computation */
  }

  if(yes) func(testfunction1());
  else    func(X);
};

如果您真的想保留当前的逻辑,那么这是一个使用placement new的自包含示例:

#include <iostream>
#include <Eigen/Dense>
using namespace Eigen;
using namespace std;

void testfunction1(Map<VectorXd> &XMap){
  double * Xnew = new double[9];
  ::new (&XMap) Map<VectorXd>(Xnew,9);
  XMap << 10, 20, 30, 40, 50, 60, 70, 80, 90;
};

int main()
{
  bool yes = true;

  VectorXd XR(9);
  XR <<  1, 2, 3, 4, 5, 6, 7, 8, 9;
  Map<VectorXd> X(XR.data(), 9);

  if(yes) testfunction1(X);

  // use X ...
  cout << X.transpose() << endl;

  // restore X and free memory allocated in testfunction1
  if(yes){
    delete[] X.data();
    ::new (&X) Map<VectorXd>(XR.data(),9);
  }

  cout << X.transpose() << endl;
}

这非常糟糕,因为如果在使用X时引发异常,它可能会泄漏。您可以通过要求testFunction1返回VectorXd(或者自己处理内存分配/释放的任何内容)来解决手动内存管理问题。并在main函数中执行new placement:

#include <iostream>
#include <Eigen/Dense>
using namespace Eigen;
using namespace std;

VectorXd testfunction1(){
  VectorXd Xnew(9);
  Xnew << 10, 20, 30, 40, 50, 60, 70, 80, 90;
  return Xnew;
};

int main()
{
  bool yes = true;

  VectorXd XR(9);
  XR <<  1, 2, 3, 4, 5, 6, 7, 8, 9;
  Map<VectorXd> X(XR.data(), 9);

  {
    VectorXd X2;
    if(yes) {
      X2 = testfunction1(); // shallow copy thanks to move semantic
      ::new (&X) Map<VectorXd>(X2.data(),9);
    }

    // use X ...
    cout << X.transpose() << endl;

    // restore X
    ::new (&X) Map<VectorXd>(XR.data(),9);
  }

  cout << X.transpose() << endl;
}

最后,如果X的内容应该是只读的,那么请在初始问题中使用Map<const VectorXd>而不是const Map<VectorXd>