У меня есть программа, которая ведет себя странно и, вероятно, имеет неопределенное поведение. Иногда обратный адрес функции, кажется, изменяется, и я не знаю, что вызывает его.Как узнать, что изменит адрес возврата функции в 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?
Вы уверены, что это поврежденный обратный адрес? Похоже, что цикл закончился без выполнения 'return a' –
В этом коде вы попадете туда (0 + 1 + 2 <3). Если в примере ошибка, попробуйте отладочную печать и ручной двоичный поиск. –
Извините, ошибка с моей стороны. Отредактирован пример. Это не мой фактический код. Я добавил точку останова на возвращаемой строке, и когда я перешел к следующей строке, она попадает в строку где-то в начале функции. Затем он переходит прямо к утверждению. – bobbaluba