【发布时间】:2013-05-07 17:12:19
【问题描述】:
和往常一样,我可能在这里遗漏了一些明显的东西。我不能发布整个源代码,因为它与工作相关,但我有一个模板化的Matrix 类,它有一个mulMM(矩阵乘以矩阵)函数和一个mulMT 函数(矩阵乘以转置矩阵)。这已经存在于代码中。我正在尝试添加一个专门用于单精度浮点值的mulMT 函数。我有一个类似的专业,mulMM,它共享相同的前两个函数参数。下面是一些示例代码:
#ifdef TARGET_x86_SSE4
template <>
Matrix<Float>& Matrix<Float>::mulMM (const Matrix<Float>& mat1,
const Matrix<Float>& mat2);
template <>
Matrix<Float>& Matrix<Float>::mulMT (const Matrix<Float>& mat1,
const Matrix<Float>& mat2,
const bool softmax);
#endif // no SSE4: use template generic
template <class BT>
Matrix<BT>& Matrix<BT>::mulMM (const Matrix<BT>& mat1,
const Matrix<BT>& mat2) {
// Function code
}
template <class BT>
Matrix<BT>& Matrix<BT>::mulMT (const Matrix<BT>& mat1,
const Matrix<BT>& mat2,
const bool softmax) {
// Function code
}
然后,在一个单独的文件中:
#ifdef TARGET_x86_SSE4
template <>
Matrix<Float>& Matrix<Float>::mulMM (const Matrix<Float>& mat1,
const Matrix<Float>& mat2) {
// Function code
}
template <>
Matrix<Float>& Matrix<Float>::mulMT (const Matrix<Float>& mat1,
const Matrix<Float>& mat2,
const bool softmax) {
// Function code
}
当我调用代码时,mulMM 正确地提取了输入矩阵的值,但是当我调用 mulMT 时,我得到了矩阵维度的随机数。使用调试器,我可以看到矩阵在进来时已经正确定义,但是一旦我进入函数,值都是错误的。这是我正在使用的一些示例代码:
MatrixFloat mA(4, 5);
MatrixFloat mB(5, 4);
// Code to initialize mA and mB's values.
MatrixFloat mR = mR.mulMM(mA, mB)
// This works fine and correctly find the values for the product.
MatrixFloat mC(4, 4)
// Code to initialize mC
mR = mR.mulMT(mC, mC)
// This fails with a memory access error and stepping into the function reveals
// that this seems to be because mC has dimensions of 84376 x 1 or thereabouts
我已经尝试让 MT 中的两个值不同。我已经验证,当我的 mulMT for Floats 不存在时,通用的可以工作。我不知道为什么这样做。
编辑:为了证明 Float 特化中的代码不是问题,我将其注释掉。一切正常。我取消了代码的注释。一切仍然有效。我在想,也许 Visual Studio 只是弄糊涂了,没有重新编译一些东西。
进一步编辑: 好的……这很奇怪。在调试时,当我第一次进入 mulMT 时,它会将我放到 const bool softmax) { 行。如果我尝试 F10,我会遇到异常。如果我按 F11,它会让我进入ChkStk.asm。如果我退出该文件,我就可以访问函数的内部并且所有内容都已正确分配。事实上,只要我不重新编译我的测试程序,我可以不出错地单步执行或运行任意多次。但是,如果我对我的测试程序进行更改并重新编译,行为就会恢复。
我比一开始更困惑。
编辑:好的,两天后没有问题,它又出现了。我认为这不是像我之前想的那样,涉及价值观的变化。相反,这是在参数实际实例化之前发生的事情。问题是,我仍然不知道为什么,除了这是我拥有的唯一一个功能,如果我在进入该功能后点击F11,它会将我放入stkchk.asm。
UnitTest.exe 中 0x00789adc 的第一次机会异常:0xC0000005:访问冲突读取位置 0xabababab。 是我得到的异常。在函数的前面,我进行了几乎相同的调用,只是改变了与运算符一起使用的变量。奇怪的是,调用周围的 try-catch 块并不能防止程序崩溃。
【问题讨论】:
-
它是否返回 Matrix
类型的本地对象?我问这个是因为您正在返回某事的参考。我建议您将其更改为指针返回。像这样的东西:模板 Matrix * Matrix ..... -
仍然缺少一些代码来一目了然可能发生的事情(例如:
MatrixFloat是什么?我猜Matrix<float>的 typedef,但谁知道...)。 -
您能否显示您使用 cmets
//function code跳过的代码?错误可能就在那里...... -
@TomásBadan 它确实在末尾返回一个 (*this) 指针,指向调用该函数的类。这不是我可以改变的,因为我正在使用现有代码。
-
不,我不能在里面发布代码,因为它是我公司使用的代码。是的,MatrixFloat 是 Matrix
的 typedef。 苦笑 我试图从代码中摘录我需要的内容。而且...最初我想说的是,在我进入函数之前,里面的代码就搞砸了,这太荒谬了。然后我注释掉了 mulMT 的 Float 专业化中的所有代码,它就起作用了。我取消了它的注释,它仍然有效。我现在更困惑了。
标签: c++ function templates overloading first-chance-exception