2017-12-21 11 views
0

Eigen :: Matrixを参照によってクラスに渡し、その中の要素にアクセスしようとしています。C++ Eigen ::クラスに渡した後に行列にアクセスできない

メイン関数とクラスの両方で再度行列にアクセスしようとすると、失敗し、行列サイズが大きい場合はセグメント化エラーが発生します。私はデバッガを使って行列の値を調べ、行列の要素にアクセスできないことを発見しました。以下は

は私のコードです:

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 
} 

それでも正しい行数と列数を返しますが、内部の要素にはアクセスできません。

なぜ機能しないのですか?どのように解決できますか?それ以外の場合は、これを適切に行うためのより良い方法がありますか?

また、私はtestLoadMat()の実行時間が行列のサイズとともに増加することに気付きました。私が「参照渡し」を間違ってやっているということですか?

+0

をごtestLoadMat関数のパラメータの種類を変更するのですか? –

答えて

0

mainのタイプは、Eigen::MatrixXfまたはMatrix<float, Eigen::Dynamic, Eigen::Dynamic>です。 testLoadMat関数でEigen::Matrix<float,3,Eigen::Dynamic>オブジェクトへの参照が必要です。これらは異なるタイプなので、正しいタイプのテンポラリ行列が作成され、testLoadMatに渡されるこの一時オブジェクトへの参照です。 testLoadMatは、この一時行列へのポインタを格納します。このポインタは、関数が復帰して一時行列が破棄されたときに無効になります。 testReadMatに電話すると、この無効なポインタを逆参照し、結果として未定義の動作が発生します。

修正はあなたが渡しているタイプと一致する。具体的には失敗します呼び出す

+0

私はすべての変数型を 'Eigen :: MatrixXf'に変更することでそれを実現しました。 さらに2つの質問: 1)行列のサイズが小さいときにコードが正常に動作するのはなぜですか?私はまだ行列の列にアクセスできます。 2)あらかじめ行番号を知っているか、すべての場合に 'Eigen :: MatrixXf'を使用することをお勧めしますか?' Eigen :: Matrix を使う利点はありますか? – mjfoo21

+0

@ mjfoo21 1)あなたはラッキーです。以前にマトリックスで使用されていたメモリは再利用されていないため(まだデータがあります)、まだ動作しています。 2)パフォーマンス。テンプレートタイプに含める具体的なデータほど、実行する必要のあるメモリ割り当てが少なくなります。詳しくは 'Matrix'テンプレートのEigenのドキュメントを参照してください。 – 1201ProgramAlarm

関連する問題