使用std::copy时出现问题

8
当我使用std复制函数时,我会收到警告。 我声明了一个byte数组。
byte *tstArray = new byte[length];

我有几个字节数组,它们被声明并用一些十六进制值初始化,我想根据一些初始用户输入来使用它们。

我有一系列if语句,基本上用于解析原始输入,并根据某些字符串选择要使用哪个字节数组,并在这样做时将结果复制到原始tstArray中。

例如:

if(substr1 == "15")
{
   std::cout<<"Using byte array rated 15"<<std::endl;
   std::copy(ratedArray15,ratedArray15+length,tstArray);
} 

我收到的警告是 警告 C4996: 'std::copy': 函数调用的参数可能不安全 - 这个调用依赖于调用者检查传递的值是否正确。

一个可能的解决方案是使用 -D_SCL_SECURE_NO_WARNINGS 来禁用此警告,我认为。好吧,这就是我正在研究的。

但是,我不确定这是否意味着我的代码真的不安全,我实际上需要进行一些检查吗?


似乎无法将代码发布...例如: if(substr1 == "15") { std::cout<<"正在使用评级为 15 的字节数组"<<std::endl; std::copy(ratedArray15,ratedArray15+length,tstArray); } - djones2010
我已经为您修复了。要发布代码,只需缩进四个空格,并在代码块之前和之后放置一个换行符。此外,编辑器中还有一个按钮,您可以使用它来自动完成这个过程。 - i_am_jorf
这意味着您已经提出了许多问题,但只有在11%的问题中点击了选中标记以接受一个答案作为“正确”答案。 - i_am_jorf
4个回答

9

C4996意味着你正在使用一个被标记为__declspec(deprecated)的函数。使用D_SCL_SECURE_NO_WARNINGS可能只会#ifdef掉过时警告。你可以去读头文件来确定。

但问题是,为什么它被弃用了?MSDN在std::copy()页面上似乎没有任何说明,但我可能看错了。通常,在XPSP2的安全推动期间,所有“不安全的字符串操作函数”都会这样做。由于你没有将目标缓冲区的长度传递给std::copy,如果你试图向其写入太多数据,它将愉快地写入缓冲区的末尾以外。

要判断你的使用是否安全,需要我们审核你的整个代码。通常,当他们以这种方式弃用一个函数时,会推荐一个更安全的版本。你可以用其他方法复制字符串。这篇文章似乎深入探讨了这个问题。他们似乎暗示你应该使用std::checked_array_iterator而不是常规OutputIterator。

像这样:

stdext::checked_array_iterator<char *> chkd_test_array(tstArray, length);
std::copy(ratedArray15, ratedArray15+length, chkd_test_array);

如果我理解你的代码正确的话。

5
checked_array_iterator 不是标准库的内容。 - UncleBens
1
是的,stdext 不是一个好玩的地方。然而,这种弃用也不是标准的。就我个人而言,我从来没有需要使用 std::copy() 来处理字符数组;我更喜欢使用 StringCchCopy(),虽然这也是 Microsoft 特有的。在可移植的代码中,我会编写一个包装器,在非 MSFT 平台上使用 strncpy()。 - i_am_jorf
1
在Microsoft平台上,“-D_SCL_SECURE_NO_WARNINGS”不是答案。请参考Howard和LeBlanc的《编写安全代码》(http://www.amazon.com/dp/0735617228)。 - jww
我同意,避免设置它。 - i_am_jorf
请查看yvals.h文件第712行。 - user5560811
显示剩余6条评论

4

基本上,这个警告告诉你要确保tstArray指向的数组足够大以容纳“length”个元素,因为std::copy不会检查这一点。


1

嗯,我假设微软单方面弃用了stdlib,也包括将char*传递给std::copy。(实际上,他们还搞乱了一系列函数。)

我想它的部分决策是有一定道理的(fopen()接触到全局ERRNO,所以不是线程安全的),但其他决定似乎不太合理。(我会说他们在整个过程中做得有些过头了。应该有不同级别,比如非线程安全、无法检查等)

我建议如果你想了解每个情况下的问题,可以阅读每个函数的MS-doc文档,其中很好地记录了为什么会有警告,并且通常每种情况的原因都不同。


-1

至少看起来 VC++ 2010 RC 在默认警告级别下不会发出该警告。


忽略警告并不是一个解决方案。在你决定忽略它之前,至少应该了解警告出现的原因。 - i_am_jorf
2
我并没有忽略它 - 我只是在说 VC++ 2010 RC 不再发出它了。 - Nemanja Trifunovic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接