我收到此警告但所有功能都正常工作。
这究竟意味着什么?
'strcpy': This function or variable may be unsafe.
Consider using strcpy_s instead. To disable deprecation,
use _CRT_SECURE_NO_WARNINGS. See online help for details.
答案 0 :(得分:22)
由于没有边界检查并且可能导致缓冲区溢出,因此该函数(strcpy)被认为是不安全的。 (实际上strcpy对于溢出漏洞是臭名昭着的,并且所有程序员都避免它 - 或者至少应该避免它)。建议是使用安全函数,该函数考虑目标缓冲区的大小以避免溢出。你也可以使用strncpy(但要小心!)。您的代码没有问题,即函数将按照您的说法运行,但尝试将大于目标缓冲区的缓冲区作为输入。该函数将溢出目标缓冲区。同时检查link text
答案 1 :(得分:11)
虽然strcpy是一个常见的字符串函数,但它有一个历史,它是软件中许多错误和安全漏洞的来源(由于缓冲区溢出很容易)。
微软为了在C和C ++中推广更安全的编码,为危险的字符串方法提供了一套替换函数。通常,它们的原始名称后跟_s。因此,strcpy的Microsoft安全版本是警告中建议的strcpy_s。请注意这是Microsoft特有的功能,它并不是无处不在。
你有几个选择。
我通常做#3。
答案 2 :(得分:10)
由于您正在编写C ++,正确的解决方案是尽可能禁止代码中的C风格char*
字符串,并将其替换为std::string
(或其他适当的字符串类型)。
不使用strcpy
或strcpy_s
或strncpy
等功能。使用string
类的复制构造函数或赋值运算符。或者,如果您确实需要复制缓冲区,请使用std::copy
。
答案 3 :(得分:8)
由于VC ++ 8 strcpy()
和一大堆其他函数are considered to be unsafe,因为它们没有边界检查,如果误用会导致缓冲区溢出。
您有两种选择:
_CRT_SECURE_NO_WARNINGS
,这将使警告消失。 答案 4 :(得分:4)
该警告基本上是告知您strcpy已弃用,因为复制字符串直到\0
很容易导致令人讨厌的问题(缓冲区溢出)。 strcpy仍然存在的原因是它是标准库遗留的一部分,但你应该考虑使用str * _s或strn *函数(它们不仅仅依赖于查找终止\0
)。
由于缓冲区溢出不仅与安全问题相关联,而且与相对难以跟踪和修复的错误相关联,因此使用普通的vanilla str *函数不仅通常不受欢迎,而且可能导致人们拒绝您的代码本身不安全的。
答案 5 :(得分:4)
实际上有一种方法可以避免这种警告,仍然使用strcpy,并且是安全的:
您可以启用secure template overloads。它们(如果可能的话)推导出使用模板化重载捕获它们所使用的缓冲区的长度。对我来说,为什么在Visual C ++中默认不启用它是一个谜。
答案 6 :(得分:2)
#pragma warning(disable: 4996)
在代码的第一行使用上面的代码。
答案 7 :(得分:1)
如果您已经了解了使用C ++纯粹技术的优缺点而不是担心,因为您“知道”您的字符串将被终止,那么您也可以在msvc中禁用警告,这类事情:
#ifdef _MSC_VER
// 4231: nonstandard extension used : 'extern' before template explicit instantiation
// 4250: dominance
// 4251: member needs to have dll-interface
// 4275: base needs to have dll-interface
// 4660: explicitly instantiating a class that's already implicitly instantiated
// 4661: no suitable definition provided for explicit template instantiation request
// 4786: identifer was truncated in debug information
// 4355: 'this' : used in base member initializer list
// 4910: '__declspec(dllexport)' and 'extern' are incompatible on an explicit instantiation
# pragma warning(disable: 4231 4250 4251 4275 4660 4661 4786 4355 4910)
#endif
答案 8 :(得分:0)
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#define _WINSOCK_DEPRECATED_NO_WARNINGS 1
在文件的顶部为我工作 (基于其他 SO 用户的回答......但我找不到推荐他/她)
答案 9 :(得分:-1)
使用Secure Template Overloads或define wrapper functions对动态分配的缓冲区不起作用,因此这种尝试是徒劳的。
修改源代码以使用安全替换,或者忽略它。
如果代码是自己编写的,最好将strcpy更改为strcpy_s等。 如果模块是从受信任的源导入的,您可以选择忽略该警告。
忽略方法1:项目全局范围:添加_CRT_SECURE_NO_WARNINGS
忽略方法2:忽略特定模块:如果只有一个或两个,那么在包含它们时你可以简单地为这些模块设置警告:
#pragma warning(push)
#pragma warning(disable: 4996)
#include <sapi.h> //legacy module
#include <sphelper.h> //legacy module
#pragma warning(pop)