Как можно читать числа с помощью sscanf сбои?
Cppcheck обнаружил потенциальную проблему в коде, подобном следующему:
float a, b, c;
int count = sscanf(data, "%f,%f,%f", &a, &b, &c);
Это говорит о том, что: "scanf без ограничений ширины поля может потерпеть крах с огромными данными" Как это возможно? Это известная ошибка в некоторых реализациях sscanf? Я понимаю, что числа могут переполняться (численно), но как программа может аварийно завершить работу? Это ложный положительный результат в cppcheck?
Я нашел похожий вопрос: scanf Cppcheck предупреждение, но ответ не является полностью удовлетворительным. Ответ упоминает безопасность типа, но это не должно быть проблемой здесь.
3 ответа
Я разработчик 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 для компиляции.
Ошибка сегментации, похоже, ошибка в glibc.
Я только что проверил это с помощью аналогичной программы, которая вылетает в Ubuntu 10.04, но работает в Ubuntu 12.04.
Как сказал Даниэль Марьямяки, его программа вылетает в 11.10, я думаю, что ошибка между ними исправлена.
ОК, рассмотрите этот код:
int main(int argc, char *argv[]) {
const char* data = "9999999999999999999999999.9999999999999999999999//i put alot more 9's there, this just to get the point through
float a;
int count = sscanf(data, "%f", &a);
printf("%f",a);
}
вывод этой программы "inf" - без сбоев. И я положил туда огромное количество девяток. Так что я подозреваю, что Cppcheck просто ошибается по этому поводу.