首先,非常抱歉这里有些具体。我通常会尽量将我的Stack Overflow问题简化为只包含相关内容的“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:我发现了问题的源头,与这段代码无关,而且也是相当明显的。真的不确定现在该怎么做这个问题。
std::array
没有以满足处理器的方式对其内容进行对齐。如果有多个线程,我会认为是竞争条件。 - Collin Dauphineestd::array
出现了问题?它怎么可能会出现问题? - Max Yankov