2

我有一个行为怪异的程序,可能有未定义的行为。有时,函数的返回地址似乎被更改了,我不知道是什么原因造成的。

返回地址始终更改为相同的地址,这是控件不应访问的函数内部的断言。我已经能够使用调试器停止程序,以查看当它应该执行 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 中打开-Walland-Werror-pedantic-errors
  • 用 valgrind 运行程序

我得到了几个invalid read of size 8,但它们似乎来自 qt,所以我不知道该怎么做。这可能是问题吗?

该错误仅在我运行程序一段时间并为其提供某些输入值时偶尔发生,并且在发布版本中比在调试版本中更常见。

编辑: 所以我设法在控制台应用程序中重现了这个问题(没有加载 qt),然后我设法模拟导致问题的事件。

就像你们中的一些人建议的那样,事实证明我误判了导致它到达断言的实际原因,可能是由于我缺乏使用 qt 调试器的经验。实际问题是用作循环条件的 double i 中的浮点错误。

我正在实现 softmax,但 exp(x) 在特定输入下四舍五入为零。

现在,既然我已经解决了这个问题,我可能会改写它。有没有一种方法可以自动检查舍入错误等问题。例如,例如在 0/0 上中断?

4

1 回答 1

1

简短的回答是:

确定是否发生浮点异常条件的最便携方法是使用 C 在 fenv.h 中提供的浮点异常工具。

尽管不幸的是,这远非完美。

我建议您阅读 https://www.securecoding.cert.org/confluence/display/seccode/FLP04-C.+Check+floating-point+inputs+for+exceptional+valueshttps://www.securecoding .cert.org/confluence/display/seccode/FLP03-C.+Detect+and+handle+floating-point+errors 简洁地解决了您提出的确切问题:

有没有一种方法可以自动检查舍入错误等问题。

于 2013-06-27T13:43:23.037 回答