2017-12-21 28 views
0

Ich versuche, eine Eigen :: Matrix als Referenz an eine Klasse zu übergeben und auf die darin enthaltenen Elemente zuzugreifen.C++ Eigen :: Zugriff auf Matrix nach dem Übergang zur Klasse nicht möglich

Wenn ich versuche, wieder die Matrix für den Zugriff auf die Haupt-Funktion und in der Klasse, versagt es und gibt Segmentierung Fehler, wenn die Matrixgröße groß ist. Ich habe einen Debugger verwendet, um die Werte der Matrix zu überprüfen und festgestellt, dass die Elemente der Matrix nicht zugänglich waren.

Unten ist mein Code:

main.cpp

Eigen::MatrixXf A = Eigen::MatrixXf::Random(3,640); //this is OK 
//Eigen::MatrixXf A = Eigen::MatrixXf::Random(3,640*480); //but not this 

std::cout << "in main A col " << A.cols() << " row " << A.rows() 
      << "\nA\n" << A.col(100) << "\n\n"; 

model.testLoadMat(A); 

model.testReadMat(); 

std::cout << "in main testMat col " << model.testMat->cols() << " row " << model.testMat->rows() 
      << "\ntestMat\n" << model.testMat->col(100) << "\n\n"; //fails here if A is large 

return 0; 

model.h

class model 
{ 
    public: 
     const Eigen::Matrix<float,3,Eigen::Dynamic> *testMat; 
     void testLoadMat(const Eigen::Matrix<float,3,Eigen::Dynamic> &tMat); 
     void testReadMat(); 
} 

model.cpp

void model::testLoadMat(const Eigen::Matrix<float,3,Eigen::Dynamic> &tMat) 
{ 
    testMat = &tMat; 

    std::cout << "in testLoadMat col " << testMat->cols() << " row " << testMat->rows() 
      << "\ntestMat\n" << testMat->col(100) << "\n\n"; 
} 

void model::testReadMat() 
{ 
    std::cout << "in testReadMat col " << testMat->cols() << " row " << testMat->rows() 
      << "\ntestMat\n" << testMat->col(100) << "\n\n"; //fails here if A is large 
} 

Sie geben immer noch die richtige Anzahl von Zeilen und Spalten, aber ich kann einfach nicht auf die Elemente im Inneren zugreifen.

Warum funktioniert es nicht und wie kann ich es lösen? Gibt es sonst eine bessere Methode, dies richtig zu machen?

Auch merke ich, dass die Zeit testLoadMat() steigt mit der Matrixgröße auszuführen. Bedeutet das, dass ich das "passing by reference" falsch mache?

+0

Welche speziell nennen macht es scheitern? –

Antwort

0

Der Typ für A in main ist Eigen::MatrixXf oder Matrix<float, Eigen::Dynamic, Eigen::Dynamic>. Ihre testLoadMat Funktion möchte einen Verweis auf ein Eigen::Matrix<float,3,Eigen::Dynamic> Objekt. Da es sich um unterschiedliche Typen handelt, wird eine temporäre Matrix des richtigen Typs erstellt, und es handelt sich um eine Referenz auf dieses temporäre Objekt, das an testLoadMat übergeben wird. testLoadMat speichert dann einen Zeiger auf diese temporäre Matrix, der ungültig wird, wenn die Funktion zurückkehrt und die temporäre Matrix zerstört wird. Wenn Sie testReadMat aufrufen, dereferenzieren Sie diesen ungültigen Zeiger, was zu Undefined Behavior führt.

Die Lösung ist den Parametertyp Ihrer testLoadMat Funktion zu ändern, um die Art passen in die Sie vorbei.

+0

Ich habe es geschafft, indem ich alle Variablentypen auf 'Eigen :: MatrixXf' ändere. Nur noch zwei Fragen: 1) Warum funktioniert der Code gut, wenn die Matrixgröße klein ist? Ich kann immer noch auf die Spalten der Matrix zugreifen. 2) Gibt es einen Vorteil mit 'Eigen :: Matrix ' wenn ich die Zeilennummer vorher weiß oder es ist nur ratsam, 'Eigen :: MatrixXf' für alle Fälle zu verwenden? – mjfoo21

+0

@ mjfoo21 1) Du hast Glück. Der Speicher, der zuvor von der Matrix verwendet wurde, wurde nicht wiederverwendet (so dass er immer noch die Daten hat, die er hatte) und den Anschein hat, dass er immer noch funktioniert. 2) Leistung. Je konkreter Daten im Schablonentyp enthalten sind, desto weniger Speicherzuweisungen müssen vorgenommen werden. Weitere Informationen finden Sie in der Eigen-Dokumentation der Matrix-Vorlage. – 1201ProgramAlarm

Verwandte Themen