为什么MSVC++认为"std :: strcat"是"不安全的"?(C++)

6 c++ warnings strcat strcat-s

当我尝试做这样的事情时:

char* prefix = "Sector_Data\\sector";
char* s_num = "0";
std::strcat(prefix, s_num);
std::strcat(prefix, "\\");
Run Code Online (Sandbox Code Playgroud)

等等,我收到警告

warning C4996: 'strcat': This function or variable may be unsafe. Consider using strcat_s instead.
Run Code Online (Sandbox Code Playgroud)

为什么strcat被认为是不安全的,有没有办法在不使用strcat_s的情况下摆脱这个警告?

另外,如果摆脱警告的唯一方法是使用strcat_s,它是如何工作的(语法方面:显然它不需要两个参数).

Eva*_*ran 29

如果你正在使用c ++,为什么不避免整个混乱和使用std::string.没有任何错误的相同示例将如下所示:

std::string prefix = "Sector_Data\\sector";
prefix += "0";
prefix += "\\"
Run Code Online (Sandbox Code Playgroud)

无需担心缓冲区大小和所有这些问题.如果你有一个需要a的API const char *,你可以使用该.c_str()成员;

some_c_api(prefix.c_str());
Run Code Online (Sandbox Code Playgroud)

  • 很高兴看到底层问题的一个很好的答案.如果可以的话,我会不止一次地投票. (4认同)

Dre*_*ins 27

因为缓冲区前缀的空间可能比复制到它的空间少,导致缓冲区溢出.因此,黑客可以传入一个特制的字符串,该字符串会覆盖返回地址或其他关键内存,并开始在程序的上下文中执行代码.

strcat_s通过强制你传入复制字符串的缓冲区的长度来解决这个问题.如果需要,它将截断字符串以确保缓冲区不会溢出.

谷歌strcat_s准确地看到如何使用它.

  • 说实话,这只是代表微软的恐慌,以确保你编写的代码不能在Windows上编译.`strcat_s`只是一个专有的`strncat`(已经存在了40年).此外,`strcat`首先不是不安全的,也不是用`strlen`提供的长度调用`strcat_s`更安全.什么是不安全的是盲目接受任意(和任意长度)的用户输入,但是使用非标准函数并不能解决这个问题,它只会在不同的函数(`strlen`)中崩溃. (3认同)

Dus*_*ell 5

您可以通过添加以下内容来消除这些警告:

_CRT_SECURE_NO_WARNINGS
Run Code Online (Sandbox Code Playgroud)

_SCL_SECURE_NO_WARNINGS
Run Code Online (Sandbox Code Playgroud)

到您项目的预处理器定义。

  • 是的,如果您想编写可移植代码,那么使用上述标志抑制警告消息是最佳选择。使用 strcat_s 可能会导致不可移植的代码,因为这是特定于 Microsoft 编译器的。 (2认同)