2013-06-03 1 views
2

У меня есть программа, которая ведет себя странно и, вероятно, имеет неопределенное поведение. Иногда обратный адрес функции, кажется, изменяется, и я не знаю, что вызывает его.Как узнать, что изменит адрес возврата функции в C++

Обратный адрес всегда изменяется на тот же адрес, что и внутри функции, недоступной для управления. Я смог остановить программу с помощью отладчика, чтобы увидеть, что, когда предполагается выполнить оператор 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 :: вектор [].at операторов для предотвращения accidentily записи в память
  • Убедился все значения возврата по- значениями являются const.
  • Включается -Wall и -Werror и -pedantic-errors в НКУ
  • Ран программы с Valgrind

Я получаю пару invalid read of size 8, но они, кажется, происходят от Qt, так что я не знаю, что делать из этого. Это может быть проблема?

Ошибка возникает только изредка, когда я запустил программу на некоторое время и дал ей определенные входные значения, а чаще всего - в сборке релиза, чем в сборке отладки.

EDIT: Так мне удалось воспроизвести проблему в консольном приложении (без кварты не загружена) Я тогда удается моделировать события, вызвавших проблему.

Как некоторые из вас предложили, оказалось, что я недооценил то, что на самом деле заставило его достичь утверждения, вероятно, из-за моего отсутствия опыта работы с отладчиком qt. Фактической проблемой была ошибка с плавающей запятой в double, которую я использовал как условие цикла.

Я реализовал softmax, но exp (x) округляется до нуля с помощью определенных входов.

Теперь, поскольку я решил проблему, я мог бы перефразировать ее. Есть ли способ проверки ошибок, таких как ошибки округления. Например, разрыв в 0/0?

+0

Вы уверены, что это поврежденный обратный адрес? Похоже, что цикл закончился без выполнения 'return a' –

+0

В этом коде вы попадете туда (0 + 1 + 2 <3). Если в примере ошибка, попробуйте отладочную печать и ручной двоичный поиск. –

+0

Извините, ошибка с моей стороны. Отредактирован пример. Это не мой фактический код. Я добавил точку останова на возвращаемой строке, и когда я перешел к следующей строке, она попадает в строку где-то в начале функции. Затем он переходит прямо к утверждению. – bobbaluba

ответ

1

Короткий ответ:

Самый переносимый способ определения, является ли плавающей точкой исключительное условие имеет место, чтобы использовать средства исключения с плавающей запятой, предоставляемые C в fenv.h.

Хотя, к сожалению, это далеко не идеальный.

Я предлагаю вам прочитать как https://www.securecoding.cert.org/confluence/display/seccode/FLP04-C.+Check+floating-point+inputs+for+exceptional+values и https://www.securecoding.cert.org/confluence/display/seccode/FLP03-C.+Detect+and+handle+floating-point+errors который доносить точный вопрос вы постановка:

Есть ли способ для проверки таких проблем, как ошибки округления автоматически.

 Смежные вопросы

  • Нет связанных вопросов^_^