Ошибка, что стек был поврежден при использовании 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;
}
Другие вопросы по тегам