C/C++

Буфер в безопасных версиях команд. strcpy_s, sprintf_s (Си)

В интернете что то этой информации не нашёл, странно.
Что такое буфер в безопасных версиях команд и чем он помогает?
Безопасные версии команд служат для того чтоб избежать переполнения буфера?
Например: char a[10]; char b[500]; strcpy(a, b);
Чем помогает защищённая версия этой команды strcpy_s ?
Буфер указывается в Байтах?

Что так
int main(){
char arr[1];
int b=1234567;
sprintf(arr, "%d", b);
printf("%s\n", arr);
}

Что так, буфер переполняется. Или нет?
int main(){
char arr[1];
int b=1234567;
sprintf_s(arr, 8, "%d", b);
printf("%s\n", arr);
}
Я так понимаю что в этом коде int трансформируется в char и на конце терминатор. Это 8 символов, 8 Байт: 1234567\0
Почему если я здесь sprintf_s(arr, 7, "%d", b); в буфер ввожу 7, то ничего не выводится на экран?
Безопасные версии не допускают переполнения буфера ( за размером буфера все так-ж должен следить программист )

В предложенном примере размер буфера 1 байт, а ты говоришь функции, что он 8 байт -> ССЗБ
СС
Сергей Сережа
89 526
Лучший ответ
Макс Костюк Получается два раза указывается размер буфера?
Здесь char arr[1];
И здесь sprintf_s(arr, 7, "%d", b);
Зачем это надо? Можно ещё 20 раз указать размер буфера, но команда от этого безопасней не станет.
Может фишка в том что можно вместо буфера в команде написать что то типа strlen(arr)*sizeof(arr)
Макс Костюк Это явно не хорошо. Я об этом ещё почитаю. Но вопрос в целом не об этом ведь.
Макс Костюк Переполнение буфера (англ. Buffer Overflow) — явление, возникающее, когда компьютерная программа записывает данные за пределами выделенного в памяти буфера.
Макс Костюк В результате переполнения могут быть испорчены данные, расположенные следом за буфером (или перед ним)
Макс Костюк Вопрос как раз как этого избежать.
Макс Костюк Хорошая статься на Википедии Переполнение_буфера. Но не о том что мне нужно сейчас.
Макс Костюк Почему так тоже ничего не выводит?
int main(){
char arr[8];
int b=1234567;
sprintf_s(arr, 7, "%d", b);
printf("%s\n", arr);
}
Макс Костюк Если изменить буфер на 8, то работает. То есть7 знаков и терминатор вмещаются. если меньше на знак, то ничего не выводит.
Может в этом тоже заключается безопасность команды?
int main(){
char arr[8];
int b=1234567;
sprintf_s(arr, 8, "%d", b);
printf("%s\n", arr);
}
#include <stdlib.h>
#include <stdio.h>
#include <corecrt.h>
int main(void) {
char good[8];
char bad[4];
int number = 1234567;
sprintf_s(good, _countof(good), "%i", number);
printf("%s\n", good);
sprintf_s(bad, _countof(bad), "%i", number);
system("pause > nul");
return 0;
}

P.S. Так как вы получаете неустранимую ошибку времени выполнения, то дальнейшее продолжение программы не имеет смысла. В режиме отладки вам придёт всплывающее окно с сообщением: Expression: ("Buffer too small", 0), что означает – Буфер слишком мал. А невозможность увеличить его размер во время выполнения, приводит к неустранимой ошибке. Нажав в окне на клавишу Продолжить (Skip), можно увидеть в этом окне сообщение: «Необработанное исключение по адресу 0x7C0DF2F6 (ucrtbased.dll) в ***.exe: Недопустимый параметр был передан функции, для которой недопустимые параметры вызывают неустранимую ошибку.»

Поняв свой косяк, вы начинаете исправляться. Так как число типа signed int может достигать 11 знаков, включая знак отрицания, то размер буфера под символьную строку с учётом 0-терминатора должен составлять 12. Изменив код на

#include <stdlib.h>
#include <stdio.h>
#include <corecrt.h>
#define BUFFER 12
int main(void) {
char good[BUFFER ];
char bad[BUFFER ];
int number = 1234567;
sprintf_s(good, _countof(good), "%i", number);
printf("%s\n", good);
sprintf_s(bad, _countof(bad), "%i", number);
system("pause > nul");
return 0;
}

ваш код станет белым и пушистым.

https://docs.microsoft.com/ru-ru/cpp/c-runtime-library/reference/sprintf-s-sprintf-s-l-swprintf-s-swprintf-s-l?view=msvc-160
ЕС
Ермек Суюнов
81 250