C++ 导致读访问冲突的特征slerp(C+;+;/OpenGL)

C++ 导致读访问冲突的特征slerp(C+;+;/OpenGL),c++,vector,eigen,quaternions,C++,Vector,Eigen,Quaternions,我正在从以下位置调用slerp(): Eigen::MatrixXf Rtime = (Eigen::Quaternionf::Identity().slerp(timer, quarts[i])).toRotationMatrix(); 其中,定时器是一个浮点数,夸脱数声明为 std::vector<Eigen::Quaternionf> quarts; 其中,U和V来自奇异值分解的计算,所以我声明四元数的方式可能有问题?或者将其存储在向量中会以某种方式影响它?我不确定。问题是

我正在从以下位置调用
slerp()

Eigen::MatrixXf Rtime = (Eigen::Quaternionf::Identity().slerp(timer, quarts[i])).toRotationMatrix();
其中,
定时器
是一个浮点数,夸脱数声明为

std::vector<Eigen::Quaternionf> quarts;

其中,
U
V
来自奇异值分解的计算,所以我声明四元数的方式可能有问题?或者将其存储在向量中会以某种方式影响它?我不确定。

问题是
Quaternionf
需要16字节的对齐,而
std::vector
不能保证这一点。更多细节。解决方案是使用对齐的分配器,例如:

std::vector<Quaternionf,Eigen::aligned_allocator<Quaternionf>> quats;
std::vector quats;
或在向量中使用不对齐的四元数:

Eigen::Matrix3f rotMatrix;
    rotMatrix = U * V;
    Eigen::Quaternionf temp;
    temp = rotMatrix;
    quarts.push_back(temp);
std::vector<Quaternion<float,Eigen::DontAlign>> quats;
std::vector quats;

问题在于
四元数f
需要16字节对齐,而
std::vector
不能保证这一点。更多细节。解决方案是使用对齐的分配器,例如:

std::vector<Quaternionf,Eigen::aligned_allocator<Quaternionf>> quats;
std::vector quats;
或在向量中使用不对齐的四元数:

Eigen::Matrix3f rotMatrix;
    rotMatrix = U * V;
    Eigen::Quaternionf temp;
    temp = rotMatrix;
    quarts.push_back(temp);
std::vector<Quaternion<float,Eigen::DontAlign>> quats;
std::vector quats;

或者将其存储在向量中以某种方式影响它?这也是我考虑的。另外,在为英特尔CPU编译时,Eigen可能需要使用特殊的数据对齐。获取对第二个端点的常量引用。你有没有试过不使用
std::vector
?@Scheff我有一个类似的程序,它不使用
std::vector
,而且运行良好。问题是我正在扩展使用范围,我需要多个四元数。我试图在相应的Triangle结构中存储一个四元数,但这也不起作用(在三角形中存储后,它似乎会对浮点值进行四舍五入)。关于
Eigen::Quaternionf::Identity()
:我真的相信返回的四元数的生存时间应该足够长,可以完成
toRotationMatrix()
。然而,这些规则很复杂,我不确定我是否完全理解它。如果有疑问,我会将其移到局部变量:
Eigen::MatrixXf Rtime=[&](){Eigen::Quaternionf::Identity quatId;return quatId.slerp(timer,quarts[I])).toRotationMatrix();}()
(使用lambda的技巧实际上是没有必要的,但它巧妙地减少了
quatId
的生命周期,就像原始版本中的临时实例一样。)如果您可以确认
std::vector
中的存储导致了问题(并且没有其他“愚蠢”的错误),当解决方法很简单时:只需将四元数复制到temp。变量。这听起来很奇怪,但我以前已经读过关于Egeng、SSE和校准问题的其他问题…@Scheff感谢您的帮助!我没有将四元数存储在
std::vector
中,而是存储了
RotMatrix
,这似乎起到了作用。或者以某种方式将其存储在向量中会影响它?这也是我考虑的。另外,在为英特尔CPU编译时,Eigen可能需要使用特殊的数据对齐。获取对第二个端点的常量引用。你有没有试过不使用
std::vector
?@Scheff我有一个类似的程序,它不使用
std::vector
,而且运行良好。问题是我正在扩展使用范围,我需要多个四元数。我试图在相应的Triangle结构中存储一个四元数,但这也不起作用(在三角形中存储后,它似乎会对浮点值进行四舍五入)。关于
Eigen::Quaternionf::Identity()
:我真的相信返回的四元数的生存时间应该足够长,可以完成
toRotationMatrix()
。然而,这些规则很复杂,我不确定我是否完全理解它。如果有疑问,我会将其移到局部变量:
Eigen::MatrixXf Rtime=[&](){Eigen::Quaternionf::Identity quatId;return quatId.slerp(timer,quarts[I])).toRotationMatrix();}()
(使用lambda的技巧实际上是没有必要的,但它巧妙地减少了
quatId
的生命周期,就像原始版本中的临时实例一样。)如果您可以确认
std::vector
中的存储导致了问题(并且没有其他“愚蠢”的错误),当解决方法很简单时:只需将四元数复制到temp。变量。这听起来很奇怪,但我以前已经读过关于Egeng、SSE和校准问题的其他问题…@Scheff感谢您的帮助!我没有将四元数存储在
std::vector
中,而是存储了
RotMatrix
,这似乎起到了作用。