我有一个行为怪异的程序,可能有未定义的行为。有时,函数的返回地址似乎被更改了,我不知道是什么原因造成的。
返回地址始终更改为相同的地址,这是控件不应访问的函数内部的断言。我已经能够使用调试器停止程序,以查看当它应该执行 return 语句时,它直接跳转到带有断言的行。
此代码近似于我的函数的工作方式。
int foo(Vector t)
double sum = 0;
for(unsgined int i=0; i<t.size();++i){
sum += t[i];
}
double limit = bar(); // bar returns a value between 0 and 1
double a=0;
for(double i=0; i<10; i++){
a += f(i)/sum; // f(1)/sum + ... + f(10)/sum = 1.0f
if(a>3)return a;
}
//shoudn'get here
assert(false); // ... then this line is executed
}
这是我迄今为止尝试过的:
- 切换所有 std::vector
[]
运算符.at
以防止意外写入内存 - 确保所有按值返回的值都是 const。
- 在 gcc 中打开
-Wall
and-Werror
和-pedantic-errors
- 用 valgrind 运行程序
我得到了几个invalid read of size 8
,但它们似乎来自 qt,所以我不知道该怎么做。这可能是问题吗?
该错误仅在我运行程序一段时间并为其提供某些输入值时偶尔发生,并且在发布版本中比在调试版本中更常见。
编辑: 所以我设法在控制台应用程序中重现了这个问题(没有加载 qt),然后我设法模拟导致问题的事件。
就像你们中的一些人建议的那样,事实证明我误判了导致它到达断言的实际原因,可能是由于我缺乏使用 qt 调试器的经验。实际问题是用作循环条件的 double i 中的浮点错误。
我正在实现 softmax,但 exp(x) 在特定输入下四舍五入为零。
现在,既然我已经解决了这个问题,我可能会改写它。有没有一种方法可以自动检查舍入错误等问题。例如,例如在 0/0 上中断?