使用 strcat_s 时堆栈损坏的错误

Error that the stack was damaged while using 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

但是弹出调试错误window,

Stack around the variable 'szPath' was corrupted. 是什么原因?

如果将szPath + strlen("C:\Program Files\")作为参数发送,则字符串的大小为sizeof(szPath) - strlen("C:\Program Files\")

第二行相同 - 大小为 sizeof(szPath) - strlen("C:\Program Files\CHS\")

字符串大小为 128,但您将指针发送到中间,可用字符数较少。

看起来 visual studio 中 strcat_s 的调试版本故意覆盖缓冲区的全长: https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strcat-s-wcscat-s-mbscat-s?view=vs-2019

The debug library versions of these functions first fill the buffer with 0xFE. To disable this behavior, use _CrtSetDebugFillThreshold.

这意味着如果您提供的大小值太大,调试运行时应该通过破坏堆栈来检测到这一点。

在您的情况下,您没有将指针传递给缓冲区的开头,因此您的大小比可用 space 多 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;
}