如何找出在c ++中更改函数返回地址的内容

时间:2013-06-03 06:24:44

标签: c++ debugging memory undefined-behavior

我有一个程序很奇怪,可能有未定义的行为。有时,函数的返回地址似乎发生了变化,我不知道是什么导致了它。

返回地址始终更改为相同的地址,控件不应该到达的函数内的断言。我已经能够使用调试器来停止程序,看看当它应该执行一个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运算符以防止意外写入内存
  • 确保所有按值返回值都是常量。
  • 在gcc中切换-Wall-Werror以及-pedantic-errors
  • 使用valgrind
  • 跑出程序

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

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

修改 所以我设法在控制台应用程序中重现问题(没有加载qt)然后我设法模拟导致问题的事件。

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

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

现在,正如我已经解决了这个问题,我可能会改写它。是否有一种方法可以自动检查舍入错误等问题。我打破0/0比如说?

1 个答案:

答案 0 :(得分:1)

简短的回答是:

  

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

但不幸的是,这远非完美。

我建议你们两个都读 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 它简明扼要地解决了你提出的确切问题:

  

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