質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.50%

  • C++

    4442questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Eigenを使用した配列をpush_backするやり方について教えてください

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 2,937

gochuumonha

score 58

今回、始めてstd::vectorとEigenを使用したのですが、どうしても自分で解決できなかったので質問させていただきました。よろしくお願いいたします。

以下のコードsample1.cppのようにEigenを用いて行列の配列を作り、それをpush_backを使って動的配列とするというようなことをやろうとしたのですが、なぜか3回目で例外がスローされて、読み取りアクセス違反となってしまいます。しかし、下のプログラムではコメントで示しているboneBaseposeMatrixList.reserve(6);を行ってメモリを確保すると意図通りに動作します。しかし、.reserve()関数はなくても.push_back()関数によって毎回メモリが確保されるものだと思います。なのでint型の値をpush_backするsample2.cppも、float型の配列をpush_backするsample3.cppも意図通りに動作するのを確認しました。(。)

sample1.cppのコードをどう変更すれば.reserve()関数を使わずにpush_backによって動的に配列に値を入れられるでしょうか?また、どうしてEigenを使用した配列がこのような挙動になるのかも教えていただけると幸いです。

//sample1.cpp
#include "stdafx.h"
#include "iostream"
#include <Eigen/Core>
#include <Eigen/Geometry>

int main (){
    std::vector<Eigen::Matrix4f> baseposeMatrixList;
    Eigen::Matrix4f baseposeMatrix = Eigen::Matrix4f::Identity();
    //invBoneBaseposeMatrixList.reserve(6);
    for (int i = 0; i < 6; ++i)
    {
        std::cout << "input_start i=" << i << std::endl;
        baseposeMatrixList.push_back(baseposeMatrix);
        std::cout << "input_end baseposeMatrix=\n" 
                << baseposeMatrix 
                << "\n" << std::endl;
    }
    return 0;
}


実行結果

input_start i=0
input_end baseposeMatrix=
1000
0100
0010
0001

input_start i=1
input_end baseposeMatrix=
1000
0100
0010
0001

input_start i=2
~ここで例外が発生し停止~
//sample2.cpp
#include "stdafx.h"
#include "iostream"
#include <Eigen/Core>
#include <Eigen/Geometry>

int main (){
    std::vector<int> vector1;
    for (int i = 0; i < 6; ++i)
    {
        vector1.push_back(i);
        std::cout << vector1[i] << std::endl;
    }
    return 0;
}
//sample3.cpp
#include "stdafx.h"
#include "iostream"
#include <Eigen/Core>
#include <Eigen/Geometry>

int main (){
    typedef union _myVector {
        float v[4];
    }myVector;
    myVector vector2;
    for (int i = 0; i < 4; ++i) vector2.v[i] = 1.0f;
    std::vector<myVector> vector2List;
    for (int i = 0; i < 6; ++i)
    {
        vector2List.push_back(vector2);
        std::cout << vector2List[i].v[0] << ":" 
                << vector2List[i].v[1] << ":" 
                << vector2List[i].v[2] << ":" 
                << vector2List[i].v[3] << std::endl;
    }
    return 0;
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

Eigen を vector などのSTLのコンテナに入れるためには、以下のようにする必要があります。

//sample1.cpp
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <Eigen/Core>
#include <Eigen/Geometry>
#include <Eigen/StdVector>

int main (){
    std::vector<Eigen::Matrix4f,Eigen::aligned_allocator<Eigen::Matrix4f> > baseposeMatrixList;
    Eigen::Matrix4f baseposeMatrix = Eigen::Matrix4f::Identity();
    //invBoneBaseposeMatrixList.reserve(6);
    for (int i = 0; i < 1000; ++i)
    {
        std::cout << "input_start i=" << i << std::endl;
        baseposeMatrixList.push_back(baseposeMatrix);
        std::cout << "input_end baseposeMatrix=\n"
                << baseposeMatrix
                << "\n" << std::endl;
    }
    return 0;
}

Eigen用の allocator を使う必要があるということです。
std::vector に Eigenのオブジェクトが 16byteアライメントされていることを知らせる必要があるのです。

詳しくは、以下を参考にしてください。
Using STL Containers with Eigen

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/12/04 04:36

    うまくいきました。
    非常にわかりやすい説明をありがとうございました。

    キャンセル

同じタグがついた質問を見る

  • C++

    4442questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。