使用 std::copy 代替手动 for 循环复制动态数组有什么好处?

问题描述 投票:0回答:4

假设我有以下代码:

int* intPtr = new int[5];

// ...do stuff...


现在我想将 intPtr 复制到一个新的、相同的数组:

int* newIntPtr = new int[5];


这可以使用简单的 for 循环或 std::copy():

来完成
  1. 使用for循环

    for (int i = 0; i < 5; i++)
        *(newIntPtr + i) = *(intPtr + i);
    
  2. 使用 std::copy()

    std::copy( intPtr, intPtr + 5, newIntPtr );
    


使用 std::copy(),我在 Visual Studio 中收到警告:

warning C4996: 'std::_Copy_impl': Function call with parameters that may be unsafe...


可以使用

stdext::checked_array_iterator<int*>
让警告消失:

std::copy(intPtr, intPtr + 5, stdext::checked_array_iterator<int*>(newIntPtr, 5));

但这意味着代码无法在 Visual Studio 之外的任何其他平台上编译。

那么,我该如何解决这个问题呢?我应该使用简单的 for 循环并有效避免警告,还是应该使用 std::copy() 并做一些事情来避免警告?显然,我可以禁用警告,但这似乎不是一个合适的解决方案......或者是吗?

c++ arrays visual-studio c++11 deep-copy
4个回答
11
投票

在循环中使用

std::copy
有一些好处:

  1. 通话是自我记录的。您的调用的读者立即知道该语句的意图是什么,而无需阅读注释或弄清楚循环正在做什么
  2. 它可能针对简单类型进行了优化,就像您的情况一样:

实际上,如果值类型是 TriviallyCopyable,std::copy 的实现会避免多重赋值并使用批量复制函数,例如 std::memmove 来源

  1. 更易于维护。您的容器将来更容易更换。只需要更改参数即可复制,无需执行

正如其他评论所提到的,循环和复制调用同样不安全,因此警告具有误导性。但是,我会避免禁用整个应用程序的安全警告。相反,请使用

#pragma warning (suppress: nnnn)
在本地禁用,请参阅此处


2
投票

最明显的优点是使用

std::copy
明确表示 你在做什么。 读者不必分析循环 弄清楚。 第二个优点是代码行数较少。 这并不是绝对的优势;有时会更冗长一些 更好。 但是当你用更少的代码行来制作代码时 更清楚,这绝对是一个优势。

对于其余的:理论上,编译器可以具有以下内置知识: 标准功能,并应用它无法做到的优化 查找用户编写的函数或循环。 在实践中,我不知道 任何编译器都这样做。


0
投票

回答您关于

std::copy
等潜在好处的问题。阿尔:

好处是,据推测,库实现可能比普通循环(例如 POD 类型的内在函数)更有效。例如,x86 上普通 C 中的

memcpy
可以更容易地优化为小尺寸的
rep movsb

至于警告:如果没有意义,应该将其报告为错误,然后禁用/忽略。

在这种情况下,针对库代码对其自身实现的调用发出的警告是无意义的,并且确实需要错误报告。


0
投票

首先使用 Copy 而不是 for 循环,这样对于大数据来说速度更快。另一方面,您收到的错误有它自己的含义,警告提醒您函数参数值可能是错误的,并且可能会在将来造成损坏。缓冲区溢出的风险。我建议您采纳编译器自己的建议并使用 -D_SCL_SECURE_NO_WARNINGS。

© www.soinside.com 2019 - 2024. All rights reserved.