本征未对齐数组断言

Eigen unaligned array assert

我有一个 class 可以找到一组二维点的凸包。它包含一个内部有 2 Eigen::Matrix<double, 2, 1> 的结构。它看起来像这样(删除了很​​多东西):

class Foo{
public:
    Foo(Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic>);

private:
    struct edge{
        unsigned int a;
        unsigned int b;
        Eigen::Matrix<double, 2, 1> slope;
        double mag;
        Eigen::Matrix<double, 2, 1> normal;
        std::vector<unsigned int> list;
    };

    Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> points;
    std::vector<edge> edges
};

向向量 edges 添加边时出现断言错误,如下所示:

void Foo::DoThing(){
    edges.push_back(edge());
}

准确的错误是:

Assertion failed: (reinterpret_cast(array) & 0xf) == 0 && "this assertio n is explained here: " "http://eigen.tuxfamily.org/dox-devel/group__TopicUnalign edArrayAssert.html" " **** READ THIS WEB PAGE !!! ****", file \blah\blah\blah\includes\eigen\eigen-eigen-dc6cfdf9bcec\eigen\src\core\densestorage.h, line 86

我去网页看了看我需要添加这个宏: EIGEN_MAKE_ALIGNED_OPERATOR_NEW 我按如下方式添加到结构中:

struct edge{
        unsigned int a;
        unsigned int b;
        Eigen::Matrix<double, 2, 1> slope;
        double mag;
        Eigen::Matrix<double, 2, 1> normal;
        std::vector<unsigned int> list;

        EIGEN_MAKE_ALIGNED_OPERATOR_NEW
    };

但错误依旧。这发生在 VS 2013 和 Eigen 版本 3.2.9 中。未经修改的相同代码适用于 3.2.0 版。在 linux 的 GCC 5.3 版中,它可以与 Eigen 的 Beta 版本一起正常工作。我在这个较新版本上做错了什么导致这个问题?

您有一个 std::vector,其中包含要对齐的固定大小的 Eigen 类型。 问题是 std::vector<edge>,其中 edge 包含固定大小对齐的 Eigen::Matrix<double, 2, 1>。 在这里,EIGEN_MAKE_ALIGNED_OPERATOR_NEW 是不够的,您还需要选择 Eigen 的对齐分配器,如 https://eigen.tuxfamily.org/dox/group__TopicStlContainers.html

中所述

Using STL containers on fixed-size vectorizable Eigen types, or classes >having members of such types, requires taking the following two steps: (i) A 16-byte-aligned allocator must be used. Eigen does provide one ready for use: aligned_allocator. (ii) If you want to use the std::vector container, you need to #include <Eigen/StdVector>.

您应该大致像这样更正您的代码(未测试):

#include<Eigen/StdVector>
class Foo { 
  ...
  std::vector<edge,Eigen::aligned_allocator<edge> > edges;
}

警告:在 Linux 上你很幸运它起作用了(可能是因为 32 位/64 位),你的代码真的应该得到纠正。