Форум программистов, компьютерный форум, киберфорум
Наши страницы

C++

Войти
Регистрация
Восстановить пароль
 
vxg
Модератор
3184 / 1987 / 227
Регистрация: 13.01.2012
Сообщений: 7,684
#1

Вызов sprintf для типа не соответствующего формату - C++

07.10.2016, 16:10. Просмотров 401. Ответов 12
Метки нет (Все метки)

Какова реакция sprintf на передачу в нее значения с типом не соответствующим указанному в формате (UB не предлагать )?
К примеру есть код
C++
1
2
3
4
int64_t x;
char buf[32];
sprintf(buf, "%i", x); //1-й вариант
sprintf(buf, "%i", (int)(x & 0xFFFFFFFF)); //2-й вариант
Оба варианта работают. Однако, программа с первым вариантом иногда падает (статистика для второго варианта еще не сформирована). Такое впечатление, что виновато не место на котором она падает, а что-то хм... большее) Что-то вроде разрушения стека. Кто-нибудь глядел что на самом деле вытворяют va_ макросы и как они извлекают аргументы? Может ли 1-й вариант как то постепенно подтачивать систему (может стек начинает дрейфовать вверх из-за несоответствия размеров типов или не знаю что)?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.10.2016, 16:10
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Вызов sprintf для типа не соответствующего формату (C++):

Считать данные из файла и записать в переменные соответствующего типа - C++
Имеется файл file.txt такого содержания(тип char*, int, float, разделенные пробелом): name 3 14.2 Как с помощью fstream считать данные из...

Считать данные из файла в динамический массив соответствующего типа - C++
Здравствуйте. Тема динамические структуры. Считать данные из файла в динамический массив соответствующего типа. 1) В файле целых...

Вызов типа - C++
Имеется объявления пипов... int*m4; int(*m5); int**m6; int(*m7)(int,float); Подскажите,как каждый можно вызвать?

Вызов конструктора текущего типа - C++
Как сделать? В шарпе можно так class MyClass { public int A,B; MyClass(int a, int b) { A = a; B =...

Написать программу для вывода символа, соответствующего коду - C++
1) Написать определение функции, вычисляющей длину строки. 2.Написать программу для вывода фамилии, номера школы и класса первого...

Соответствие типа мака, его формату записи - Python
Здравствуйте. Помогите советами по задаче. Как лучше решить? задача: Соответствие типа мака, его формату записи: 0: AA-BB-CC-DD-EE-FF...

12
Nick Alte
Эксперт С++
1641 / 1013 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
07.10.2016, 18:13 #2
В данном случае реакция должна быть простейшая, использование 4 байтов из переданного аргумента. Стек чистится в месте вызова, так что данный вызов не должен приводить к ошибкам.

Цитата Сообщение от vxg Посмотреть сообщение
Кто-нибудь глядел что на самом деле вытворяют va_ макросы и как они извлекают аргументы?
Предельно тупо, получают адрес последнего перед эллипсисом аргумента и далее смещают этот адрес на размер очередного извлекаемого типа.

Цитата Сообщение от vxg Посмотреть сообщение
может стек начинает дрейфовать вверх из-за несоответствия размеров типов
Не должен дрейфовать, его чистит вызывающая сторона, которая знает, что и сколько передавала в аргументах.
1
vxg
Модератор
3184 / 1987 / 227
Регистрация: 13.01.2012
Сообщений: 7,684
07.10.2016, 18:27  [ТС] #3
Nick Alte, получается самое плохое это если принимающая сторона прочитает какую-либо чудь из стека из-за неправильных типов? Это может вызвать AV?
0
Avazart
Эксперт С++
7247 / 5419 / 297
Регистрация: 10.12.2010
Сообщений: 24,054
Записей в блоге: 17
07.10.2016, 21:49 #4
Почему не использовать потоки?
C++
1
2
3
4
int64_t x;
std::stringstream ss;
ss << x;
std::string buf= ss.str();
Как реализована функция printf
1
vxg
Модератор
3184 / 1987 / 227
Регистрация: 13.01.2012
Сообщений: 7,684
08.10.2016, 07:57  [ТС] #5
Avazart, да, можно использовать и поток, но вопрос пока касается не его. Впрочем, вы угадали что все это - аналоги IntToStr, может есть ещё варианты?
0
Nick Alte
Эксперт С++
1641 / 1013 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
08.10.2016, 10:35 #6
Цитата Сообщение от vxg Посмотреть сообщение
Это может вызвать AV?
Может в том случае, если в строке формата указано нечто указателеобразное (%s, может ещё кто-то, не помню точно).
1
vxg
Модератор
3184 / 1987 / 227
Регистрация: 13.01.2012
Сообщений: 7,684
08.10.2016, 10:39  [ТС] #7
Nick Alte, нет, там только %i вместо которого передаётся int64_t и даже интерпретируя его как int мы всего лишь попадём в его верхние 4 байта
0
Nick Alte
Эксперт С++
1641 / 1013 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
08.10.2016, 10:50 #8
Цитата Сообщение от vxg Посмотреть сообщение
там только %i вместо которого передаётся int64_t
В этом случае стеку ничего не сделается. Может быть, проблема в другом месте? Или может она возникает из-за отладочных проверок?
1
Avazart
Эксперт С++
7247 / 5419 / 297
Регистрация: 10.12.2010
Сообщений: 24,054
Записей в блоге: 17
08.10.2016, 10:57 #9
Цитата Сообщение от vxg Посмотреть сообщение
Nick Alte, нет, там только %i вместо которого передаётся int64_t и даже интерпретируя его как int мы всего лишь попадём в его верхние 4 байта
По идее проблема может возникать когда следом идет еще несколько аргументов, смещение может идти не верное и следующий арг. будет писаться из оставшихся 4 байт int64_t первого аргумента.

Цитата Сообщение от vxg Посмотреть сообщение
Avazart, да, можно использовать и поток, но вопрос пока касается не его. Впрочем, вы угадали что все это - аналоги IntToStr, может есть ещё варианты?
boost::lexical_cast<>
boost::format()

Не по теме:

Я недавно свой велосипед пытался написать:
https://github.com/Avazart/Bicycle/b...ain_Format.cpp
https://github.com/Avazart/Bicycle/b...ental/Format.h

1
vxg
Модератор
3184 / 1987 / 227
Регистрация: 13.01.2012
Сообщений: 7,684
08.10.2016, 11:03  [ТС] #10
Avazart, жаль что только буст
0
Avazart
Эксперт С++
7247 / 5419 / 297
Регистрация: 10.12.2010
Сообщений: 24,054
Записей в блоге: 17
08.10.2016, 11:26 #11
До С++11 только потоки, boost и фрейворки
После С++11 to_string() и компания.

Там написано что используется тот же std::sprintf так что попробуйте через:
C++
1
std::sprintf(buf, "%lld", value) // std::string to_string( long long value );
Добавлено через 4 минуты
Странно что таких функций в С++ долго не хватало, а когда их ввели, все равно не продумали форматирование/локализацию/преобразование без выкидывания исключения.
1
vxg
Модератор
3184 / 1987 / 227
Регистрация: 13.01.2012
Сообщений: 7,684
08.10.2016, 14:06  [ТС] #12
Avazart, я просто опасаюсь что %lld будет платформзависимым
0
Avazart
Эксперт С++
7247 / 5419 / 297
Регистрация: 10.12.2010
Сообщений: 24,054
Записей в блоге: 17
08.10.2016, 15:34 #13
Цитата Сообщение от vxg Посмотреть сообщение
Avazart, я просто опасаюсь что %lld будет платформзависимым
int64_t скорее всего приводится long long который платформозависим, но начиная с С++11 вроде как long long не меньше 64 бит поэтому проблем не должно быть, но на всякий случай стоит поставить assert для проверки размера типа.
1
08.10.2016, 15:34
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.10.2016, 15:34
Привет! Вот еще темы с ответами:

Вызов оператора false для объекта обобщенного типа - C#
Добрый вечер. По заданию нужно было перегрузить оператор false(как понимаю, с этим я справился). Но вот как теперь вызвать этот оператор?...

Реализация IEnumerable<T>: GetEnumerator не имеет соответствующего возвращаемого типа - C#
Здравствуйте. Помогите пожалуйста разобраться с реализацией IEnumerable&lt;T&gt;. public class Group : IEnumerable&lt;Student&gt; { //... ...

Как получить менеджер объекта, зная значение соответствующего типа? - 1С
всем привет Задача - как получить менеджер объекта зная значение соответствующего типа? вот к примеру у меня есть значение типа...

Документация по формату ELF для написания загрузчика - Assembler
Я пишу загрузчик ELF(правда на СИ). И есть ли у кого документация ELF на русском. У меня есть только на английском - языке, которого я не...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru