Ошибка, что стек был поврежден при использовании strcat_s
Я учился strcat_s
и я написал следующий код, чтобы попрактиковаться в этом.
int main(void)
{
char szPath[128] = { "C:\\Program Files\\" };
strcat_s(szPath + strlen("C:\\Program Files\\"), sizeof(szPath), "CHS\\");
strcat_s(szPath + strlen("C:\\Program Files\\CHS\\"), sizeof(szPath), "C programming");
puts(szPath);
return 0;
}
Выход работал правильно, как
C:\Program Files\CHS\C programming
но появилось окно с ошибкой отладки,
Stack around the variable 'szPath' was corrupted.
В чем причина?
2 ответа
Если вы отправите szPath + strlen("C:\\Program Files\\")
в качестве параметра размер строки равен sizeof(szPath) - strlen("C:\\Program Files\\")
.
То же самое для второй строки - размер sizeof(szPath) - strlen("C:\\Program Files\\CHS\\")
.
Размер строки 128, но вы отправляете указатель на середину, где количество доступных символов меньше.
Похоже на отладочную версию strcat_s
в Visual Studio намеренно перезаписывает всю длину буфера:https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strcat-s-wcscat-s-mbscat-s?view=vs-2019
Версии библиотеки отладки этих функций сначала заполняют буфер 0xFE. Чтобы отключить это поведение, используйте _CrtSetDebugFillThreshold.
Это означает, что если вы укажете слишком большое значение размера, среда выполнения отладки должна обнаружить это, повредив стек.
В вашем случае вы не передаете указатель на начало буфера, поэтому ваш размер strlen
байтов больше доступного места. Самое простое решение - просто передать указатель без изменений вstrcat_s
, это делает strlen
внутренне, чтобы найти текущий конец строки:
int main(void)
{
char szPath[128] = { "C:\\Program Files\\" };
strcat_s(szPath, sizeof(szPath), "CHS\\");
strcat_s(szPath, sizeof(szPath), "C programming");
puts(szPath);
return 0;
}