Неожиданный вывод printf…WEBphoenix
Поведение printf
не определено, потому fprintf что оно не может обрабатывать c ID
как строку, также известную c-strings как массив символов с нулевым c-strings завершением, функция printf
, учитывая cstring спецификатор формата %s
, полагается vswprintf на этот нулевой терминатор, чтобы snprintf знать где остановить печать. Поскольку undefined-behavior нулевой байт не найден, он fprintf переполнит массив в соседней printf памяти, ища его, и напечатает undefined-behaviour все, что там есть. Так уж printf случилось, что в этой области undefined-behavior находится другой массив символов vsprintf Buffer
, и это то, что печатается, это snprintf может быть что-то совершенно c-strings другое, включая ожидаемый output результат, если случайно vsprintf в первом байте этой непрерывной undefined-behavior памяти был обнаружен нулевой output байт, обратите внимание на undefined-behaviour определение undefined behavior:
Поведение при использовании непереносимой или ошибочной программной конструкции или ошибочных данных, для которых настоящий стандарт не устанавливает требований.
Возможное неопределенное поведение варьируется от полного игнорирования ситуации с непредсказуемыми результатами до документированного поведения во время трансляции или выполнения программы, характерного для среды […]
Большинство c-string компиляторов и соответствующих c-strings версий, которые я тестировал, действительно vswprintf ведут себя так, как вы описываете, и c-string печатают оба массива последовательно, хотя output и не все из них. Это не шаблон, на c который вы можете положиться, как vswprintf вы можете видеть здесь:
https://godbolt.org/z/1E396Y3KG (gcc snprintf с оптимизацией)
Или здесь:
https://godbolt.org/z/roa6GxWvr (msvc)
Результат vsprintf не всегда abcde0123456789
.
Что касается причины, по snprintf которой он не имеет нулевого output терминатора ('\0'
), это потому, что snprintf для него недостаточно места, если snprintf вы объявите размер как имеющий c лишний элемент, он будет snprintf автоматически добавлен компилятором:
char ID[6] = "abcde"; //will automatically append \0 to the char array ^
На snprintf самом деле лучше не указывать c размер, компилятор выведет output необходимый размер без необходимости vsprintf подсчитывать символы, и поэтому cstring он менее подвержен ошибкам:
char ID[] = "abcde";
c
output
printf
c-strings
undefined-behavior
2022-11-25T09:44:33+00:00 2022-11-26T09:54:41+00:00 Wyoming
Вопросы с похожей тематикой, как у вопроса:
Неожиданный вывод printf
Re Устаревший код: формат «% d» ожидает аргумент типа «int», но аргумент 3 имеет тип «long unsigned int» [-Wformat]
Безопасен ли sprintf (buffer, «% s […]», buffer, […])?
Можно ли распечатать только определенный участок C-строки, не создавая отдельной подстроки?
Как добавить строку перед строкой в C
‘\ 0’ и printf() в C
Printf небезопасно использовать в C
В чем разница между printf() и put() в C?
Что предпочтительнее — printf или fprintf
C / C++ printf() перед проблемой scanf()
Добавить вывод команды в файл без новой строки
Как записать в файл с помощью open() и printf()?
Форматирование вывода с помощью printf: усечение или заполнение
Важна ли проверка возвращаемого значения printf?
Каково обычное поведение undefined/unspecified для C, с которым вы сталкиваетесь?
Переполнение буфера на основе стека в fprintf в musl до 0.
8.8 и более ранних версиях позволяет контекстно-зависимым злоумышленникам вызывать де CVE-2012-2114 : Переполнение буфера на основе стека в fprintf в musl до 0.8.8 и более ранних версиях позволяет зависимые злоумышленники, чтобы вызвать де(например: CVE-2009-1234 или 2010-1234 или 20101234)
Переключиться на https://
Дом Просмотр : |
|
CVE является зарегистрированным товарным знаком корпорации MITRE, а официальным источником содержания CVE является CVE-сайт MITRE. CWE является зарегистрированным товарным знаком корпорации MITRE, а официальным источником контента CWE является Веб-сайт CWE MITRE. OVAL является зарегистрированным товарным знаком The MITRE Corporation, а официальным источником контента OVAL является Веб-сайт MITRE OVAL.
Использование этой информации означает согласие на использование в состоянии КАК ЕСТЬ. НИКАКИХ гарантий, подразумеваемых или иных, в отношении этой информации или ее использования. Любое использование этой информации осуществляется на риск пользователя. Пользователь несет ответственность за оценку точности, полноты или полезности любой информации, мнения, совета или другого контента. КАЖДЫЙ ПОЛЬЗОВАТЕЛЬ НЕСЕТ ЕДИНСТВЕННУЮ ОТВЕТСТВЕННОСТЬ ЗА ЛЮБЫЕ последствия его или ее прямого или косвенного использования данного веб-сайта.