需要彻底替换对 std::copy 的可能不安全的调用

Posted

技术标签:

【中文标题】需要彻底替换对 std::copy 的可能不安全的调用【英文标题】:Need a clean replacement to a possibly unsafe call to std::copy 【发布时间】:2013-09-04 03:43:43 【问题描述】:

我知道有更好的选择,例如 std::vectorstd::array 等。在我的情况下,我必须使用指向动态分配数组的指针,因为我正在学习复制和交换习语和它涉及创建我自己的资源管理类。

假设我有一个资源句柄类的以下复制构造函数:

A(const A& other) : size(other.size), arr(size ? new int[size]() : nullptr) 
    std::copy(other.arr, other.arr + size, arr);

它不能在 Visual Studio(2013 Preview 和 2012 Express)中编译。我得到的错误是:

是否可以以另一种方式使用std::copy,以便编译器停止对我大喊大叫?或者使用简单的循环手动复制数组的内容是一个更好的主意,比如

for (int i = 0; i < size; i++) 
    arr[i] = other.arr[i];

附:我不想使用任何黑客/宏来禁用警告等。

【问题讨论】:

它大喊大叫,因为如果大小很大,可能会出现缓冲区溢出。如果可能的话,您的用法可能会清楚地表明这一点。您可以仅禁用此文件的警告。 ***.com/questions/903064/… @JesseGood 在这个例子中是一个简单的int* 为什么不使用std::vector&lt;int&gt; 如果 Visual Studio 拒绝编译符合 C++ 的代码,那么它就不是 C++ 编译器。换句话说,您的问题是关于 Visual Studio,而不是关于 C++。 @Nemo:你在草率下结论。 c4996 是一个警告。如果触发错误,则 OP 自己启用了“将警告视为错误”标志。 【参考方案1】:

据我所知,您已在项目中启用“将警告视为错误”(请参阅/WXhere)。禁用标志,重新编译。在 windows+msvc 上启用此标志不是一个好主意,因为有些警告简直是疯了(在任何包含 windows.h 的程序中尝试 /Wall/W4)。

要消除警告,请在项目属性中#define D_SCL_SECURE_NO_WARNINGS。或者将容器替换为vector。您还可以使用编译器编译指示禁用特定警告。

【讨论】:

+1 用于禁用无意义的警告。误报是最坏的警告情况......【参考方案2】:

您有多种选择:

1) 定义D_SCL_SECURE_NO_WARNINGS,如错误消息所述。另外,您是否打开了“将警告变为错误”?看来这应该是一个警告,而不是一个错误。 (编辑:我现在看到您不想使用这种方法)。

2) 使用checked_array_iterator(不过,这不是标准的):

std::copy(other.arr, other.arr + size, stdext::checked_array_iterator<int*>(arr, size));

3) 使用std::vector,这是最好的方法。

【讨论】:

+1 表示第二个选项。不过有一个问题,在普通的std 中是否有checked_array_iterator 的替代品? @Oleksiy:不,没有。即使在我的链接中也显示To avoid the need for the checked_array_iterator class when using Standard C++ Library algorithms, consider using a vector instead of a dynamically allocated array.

以上是关于需要彻底替换对 std::copy 的可能不安全的调用的主要内容,如果未能解决你的问题,请参考以下文章

为啥我需要另一个迭代器作为 std::copy() 中的参数?

空范围的 std::copy() 或 std::move() 是不是需要有效目的地?

真牛掰!阿里人用5个案例就彻底讲清了SpringSecurity安全框架

使用 std::copy 复制数组时出现分段错误

std::copy、std::copy_backward 和重叠范围

彻底理解 HDFS 的安全模式