需要彻底替换对 std::copy 的可能不安全的调用
Posted
技术标签:
【中文标题】需要彻底替换对 std::copy 的可能不安全的调用【英文标题】:Need a clean replacement to a possibly unsafe call to std::copy 【发布时间】:2013-09-04 03:43:43 【问题描述】:我知道有更好的选择,例如 std::vector
或 std::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<int>
?
如果 Visual Studio 拒绝编译符合 C++ 的代码,那么它就不是 C++ 编译器。换句话说,您的问题是关于 Visual Studio,而不是关于 C++。
@Nemo:你在草率下结论。 c4996 是一个警告。如果触发错误,则 OP 自己启用了“将警告视为错误”标志。
【参考方案1】:
据我所知,您已在项目中启用“将警告视为错误”(请参阅/WX
here)。禁用标志,重新编译。在 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安全框架