如何摆脱Visual Studio中的"不安全"警告/错误(strcpy,sprintf,strdup)

And*_*dre 21 c++ windows debugging visual-studio

我试图摆脱一些编译器警告说strcpy,sprintf等是不安全的.我明白他们为什么不安全,但我想不出一个以C++风格修复代码的好方法.

这是代码的摘录:

extList->names[i]=(char *)malloc(length*sizeof(char));
strcpy(extList->names[i],extName);                     // unsafe
// strncpy(extList->names[i],extName,length);          // also unsafe
Run Code Online (Sandbox Code Playgroud)

这是消息:

C4996:'strcpy':此函数或变量可能不安全.请考虑使用strcpy_s.要禁用弃用,请使用_CRT_SECURE_NO_WARNINGS.详细信息请参见在线帮助.

在不知道要复制的东西的长度的情况下,我想不出用C++复制数据的安全方法.我知道有strlen(),但这也是不安全的,因为它假定(可能不正确)数据是以空值终止的.

也:

// used to concatenate:
sprintf(extStr,"%s%s",platExtStr,glExtStr);
Run Code Online (Sandbox Code Playgroud)

C4996:'sprintf':此函数或变量可能不安全.请考虑使用sprintf_s.要禁用弃用,请使用_CRT_SECURE_NO_WARNINGS.详细信息请参见在线帮助.

使用std :: string来连接很容易,但是我需要以某种方式将数据输入extStr(而不是使用strcpy,lol).string :: c_str()函数返回一个指向不可修改数据的指针,所以我不能只设置extStr等于它.(我甚至不确定c_str()指针是否需要稍后调用它?是否使用"new"分配空间?)

关于这个东西的任何建议?这是10,000行文件的一部分,而不是我的......所以我并不热衷于用C++方式重写这个东西.

Sig*_*erm 35

你真的不需要编译指示来禁用它们.

对于win32/msvc,在ProjectProperties - >配置属性 - > C/C++ - >预处理器 - >预处理器定义中,添加以下宏:

_CRT_SECURE_NO_DEPRECATE  
_CRT_NONSTDC_NO_DEPRECATE
Run Code Online (Sandbox Code Playgroud)

或者您可以在命令行参数中传递thos(-D_CRT_SECURE_NO_DEPRECATE).您可以在某些*.cpp文件的开头#define它们.此外,可能还有更多(见crtdefs.h - 看起来有很多......).这些警告通常会告诉您哪些宏可以禁用它们 - 只需读取编译器输出.

  • `_CRT_NO_MICROSOFT_JEDI_MIND_CONTROL` 将是一个方便的设置。 (2认同)

Pap*_*ome 7

这是这个问题的另一个答案.

#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4996)
#endif

        strcpy(destination, source);

#ifdef _MSC_VER
#pragma warning(pop)
#endif
Run Code Online (Sandbox Code Playgroud)


小智 6

如果只删除警告是你的目标......只需定义 _CRT_SECURE_NO_WARNINGS它,它将禁止所有弃用警告.但这不会解决不安全的CRT功能的潜在问题.

如果你在Visual Studio的版本> = 2005,并希望以适当的方式来解决这些警告......最简单的方法就是#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT 1你的项目.

没有任何进一步的代码更改,您可以观察到大多数警告是自动修复的.通过定义此窗口将自动调用大多数不安全CRT函数的安全重载函数.静态数组的缓冲区大小自动计算.

虽然动态分配的缓冲区不是通过这种方式修复的,但我们需要手动修复它们.有关详细信息,请参阅此链接.

下面是一种以编程方式更正示例的方法

strcpy_s(extList->names[i], length, extName); 
Run Code Online (Sandbox Code Playgroud)


djn*_*jna 5

你知道要复制多少 - 你为它分配了空间!

当然你不会心甘情愿地复制超过你分配的空间吗?

我更喜欢使用一种方法,通过限制复制的项目数来明确避免缓冲区溢出.当我是一名C程序员时,我们使用了

dest = malloc(len);         // note: where did we get len?
if ( dest is null )  panic!  // note: malloc can fail
strncpy(dest, src, len);
dest[len-1] =0;
Run Code Online (Sandbox Code Playgroud)

这有点凌乱,并且已经指出使用strncpy()方法,该方法最初设计用于固定宽度字段而不是字符串.然而它确实很痛苦

有一些方法,如strdup()和strlcpy(),我们可以提供帮助.

我的建议:

1).你的目标不应该是抑制警告,而是要使代码健壮.

2).复制字符串时,您需要确保以下事项:

  • 保护自己免受不良输入,例如未终止或过长的字符串.
  • 保护自己免受malloc故障的影响
  • 强烈倾向于复制计数的字符数,直到我们看到空值
  • 如果您声称要构建一个字符串,那么请务必确保null终止它

如果您的环境中有strlcpy(),那么您可以使用它,否则为什么不编写自己的小实用函数?然后,如果只有那个功能有警告你已经本地化然后问题.

  • `strncpy`是[不适用于C字符串](http://stackoverflow.com/questions/2884874/when-to-use-strncpy-or-memmove/2884974#2884974).根据具体情况,可以使用`strlcpy`或`memcpy`. (3认同)