Как можно считывать числа с помощью sscanf crash?
Cppcheck обнаружил потенциальную проблему в коде, подобном этому:
float a, b, c;
int count = sscanf(data, "%f,%f,%f", &a, &b, &c);
В нем говорится, что: "scanf без ограничений ширины поля может сбой с огромными данными". Как это возможно? Это известная ошибка в некоторых реализациях sscanf? Я понимаю, что числа могут переполняться (численно), но как может сбой программы? Это ложный позитив в cppcheck?
Я нашел аналогичный вопрос: scanf Cppcheck warning, но ответ не полностью удовлетворяет. В ответе упоминается безопасность типов, но это не должно быть проблемой.
Ответы
Ответ 1
Я разработчик Cppcheck.
Да, это странный крах. С "огромными данными" это означает миллионы цифр.
Если вы используете флаг --verbose, тогда cppcheck на самом деле напишет небольшой примерный код, который обычно сбой на компьютерах linux.
Вот пример кода, который сбой сегментации на моем компьютере Ubuntu 11.10:
#include <stdio.h>
#define HUGE_SIZE 100000000
int main()
{
int i;
char *data = new char[HUGE_SIZE];
for (int i = 0; i < HUGE_SIZE; ++i)
data[i] = '1';
data[HUGE_SIZE-1] = 0;
sscanf(data, "%i", &i);
delete [] data;
return 0;
}
Для вашей информации я не получаю сбои, когда я пробую этот примерный код на visual studio.
Я использовал g++ версию 4.6.1 для компиляции.
Ответ 2
Ошибка сегментации, похоже, является ошибкой в glibc.
Я только что проверил это с помощью подобной программы, которая вылетает в ubuntu 10.04,
но работает в ubuntu 12.04.
Как сказал Даниэль Марьямяки, его программа вылетает в 11.10, я считаю, что ошибка
между ними.
Ответ 3
ОК, рассмотрите этот код:
int main(int argc, char *argv[]) {
const char* data = "9999999999999999999999999.9999999999999999999999//i put alot more 9 there, this just to get the point through
float a;
int count = sscanf(data, "%f", &a);
printf("%f",a);
}
вывод этой программы - "inf" - без сбоев. И я поставил там огромное количество 9. Поэтому я подозреваю, что Cppcheck просто ошибается.