2017-09-05 13 views
2

Eigen :: Map 객체에 대한 포인터를 정의 할 수 있습니까? 원래 코드 (의사 코드) 매우 복잡하지만, 여기에 내가 달성하기 위해 노력하고 무엇을지도 본질적으로 이미 포인터이기 때문에이 갱신되도록 간단 할 것이다, 그래서 여기에 포인터를 사용하는 전혀 필요Eigen :: Map <Eigen :: VectorXd> 객체에 대한 C++ 고유 포인터

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? 

}; 

답변

0

우선 placement new의 Map 객체 그럼에도 불구하고 현재 설계는 testfunction1 내 할당과 testfunction2 내의 할당 해제가 필요할 경우 할당해야합니다. 이는 실제로 안전하지 않습니다. 그래서 더 나은 함수 내에서 "약간의 계산을"넣어 기능적인 디자인을 채택 (또는 명명 된 람다), 가치에 의하여 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); 
}; 

당신이 정말로 당신의 현재 논리를 유지하려는 경우, 여기에 자체입니다 -contained 예를 들어 새로운 배치를 사용하여 : 예외가 메모리를 처리 VectorXd (또는 아무것도를 반환 testFunction1을 요청함으로써 당신은 수동으로 메모리 관리를 해결 할 수 X를 사용할 때 발생하는 경우가 누출 할 수 있기 때문에 아주 나쁜

#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; 
} 

할당/할당 취소 자체)를 수행하고 주요 기능에서 배치를 새로 수행합니다 N : X의 내용이 읽기 전용으로 할 필요가있는 경우

#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; 
} 

마지막으로, 당신의 초기 문제로 Map<const VectorXd>하지 const Map<VectorXd>를 사용합니다.

+0

답장을 보내 주셔서 감사합니다. 이것은 현재의 나의 코드가하고있는 일이지만 if else 문이 다른 func을 필요로하기 때문에 읽기가 어렵습니다. 그러나 다른 사람들에게 유용 할 수 있으므로 대답을 받아 들일 것입니다. 그러나, 나는 여전히지도에 대한 포인터를 선언하는 방법을 궁금해합니다 <...> – itQ

+0

'typedef const MapVectorXd ConstMapVectorXd;'를 선언하고 'ConstMapVectorXd *'를 사용합니다. 그러나 참조 된 데이터 모두에 대해 복잡한 동적 메모리 할당을 처리해야합니다. 새로운 Map과 Map 객체 자체는 항상 오류와 메모리 누수가 발생하기 쉽습니다. [placement new] (https://eigen.tuxfamily.org/dox/group__TutorialMapClass.html#title3)을 사용하여 Map 객체 자체를 수정하면 참조 된 데이터의 할당/할당 해제를 처리해야합니다. 더 좋고 만족스럽지 않습니다. – ggael

+0

당신의 완전한 대답은 단지 완벽합니다! 큰 감사! – itQ