首先-很抱歉。我通常会尝试将SO问题简化为仅包含相关内容的通用“ A类”内容,但是我不确定这里的问题根源是什么。
我有一个矩阵类模板,看起来像这样(仅显示我认为是相关的部分):
template <std::size_t R, std::size_t C>
class Matrix
{
private:
//const int rows, cols;
std::array<std::array<float,C>,R> m;
public:
inline std::array<float,C>& operator[](const int i)
{
return m[i];
}
const std::array<float,C> operator[](const int i) const
{
return m[i];
}
template<std::size_t N>
Matrix<R,N> operator *(const Matrix<C,N> a) const
{
Matrix<R,N> result = Matrix<R,N>();
// irrelevant calculation
return result;
}
// ... other very similar stuff, I'm not sure that it's relevant
}
template <std::size_t S>
Matrix<S,S> identity()
{
Matrix<S,S> matrix = Matrix<S,S>();
for(std::size_t x = 0; x < S; x++)
{
for(std::size_t y = 0; y < S; y++)
{
if (x == y)
{
matrix[x][y] = 1.f;
}
}
}
return matrix;
}
我对整个课程进行了单元测试,乘法和身份工厂都似乎正常工作。但是,然后我在此方法中使用了它,它被调用了很多次(我认为,如果您曾经编写过渲染器,那么我在这里要做的事情就很明显了):
Vec3i Renderer::world_to_screen_space(Vec3f v)
{
Matrix<4,1> vm = v2m(v);
Matrix<4,4> projection = identity<4>(); // If I change this to Matrix<4,4>(), the error doesn't happen
projection[3][2] = -1.f;
vm = projection * vm;
Vec3f r = m2v(vm);
return Vec3i(
(r.x + 1.) * (width / 2.),
(r.y + 1.) * (height / 2.),
r.z
);
}
经过一段时间和对该方法的一些随机调用之后,我得到了:
Job 1, 'and ./bin/main' terminated by signal SIGBUS (Misaligned address error)
但是,如果我改线identity<4>()
到Matrix<4,4>()
错误不会发生。我是C ++的新手,所以它一定很愚蠢。
因此,(1)此错误是什么意思,(2)我如何设法用腿射击自己?
更新:当然,此错误不会在LLDB调试器中重现。
更新2:这是通过Valgrind运行程序后得到的结果:
==66525== Invalid read of size 4
==66525== at 0x1000148D5: Renderer::draw_triangle(Vec3<float>, Vec3<float>, Vec3<float>, Vec2<int>, Vec2<int>, Vec2<int>, Model, float) (in ./bin/main)
而draw_triangle
正是调用world_to_screen_space
和使用它的结果的方法。
更新3:我发现了问题的根源,它与该代码无关,而且也很明显。真的不知道现在该怎么办。
如果没有检查不对齐的处理器(如@twalberg所说),就不可能运行和验证代码。但是我可以这样说:将一种异常与另一种异常混淆是C ++或其他库中的常见错误。
我的猜测-很抱歉,我无法做更多-是您正在创建丢失的分配,用尽了可用的内存,然后溢出了内存空间。当您超出可用内存时,抛出的非常罕见的异常可能是意外的,并作为未对齐错误返回。尝试在运行时检查内存使用情况,以确定是否可能是这种情况。
编辑:
我的猜测是错误的,并且valgrind输出显示错位的地址错误是正确的。运行那是一个好主意。明确的指示是,存在一个比您的代码更低级别的错误,因此我的最初想法几乎可以肯定是正确的:存在一个不在您的代码中但被掩盖的错误。
请注意,identity()构造函数与Matrix <,>构造函数之间似乎存在差异,因为前者是沿对角线初始化的(缓慢:最好是消除内部循环),而后者则不是。这可能会影响v2m和m2v的行为。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句