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

时间:2015-03-17 12:51:31

标签: c++ arrays visual-studio c++11 deep-copy

假设我有以下代码:

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 );
    

  3. 使用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()并做一些事情来避免警告?显然,我可以禁用警告,但这似乎不是一个合适的解决方案......或者是它?

4 个答案:

答案 0 :(得分:4)

在循环中使用std::copy有一些好处:

  1. 电话是自我记录的。您的电话会议的读者立即知道该声明的意图,而无需阅读评论或弄清楚循环正在做什么
  2. 可以针对简单类型进行优化,例如:
  3.   

    实际上,如果值类型为TriviallyCopyable,则std :: copy的实现会避免多个赋值并使用批量复制函数,例如std :: memmove   source

    1. 更易于维护。您的容器将来更容易更换。您只需要更改要复制的参数而不是实现
    2. 正如其他评论所提到的,循环和复制调用同样不安全,因此警告具有误导性。但是,我会避免禁用整个应用程序的安全警告。而是使用#pragma disable

      在本地禁用

答案 1 :(得分:1)

最明显的优势是使用std::copy明确说明 你在做什么。读者不必分析循环 想办法。第二个优点是它的代码行数较少。 这不是绝对的优势;有时候更冗长一点 更好。但是当你使用较少的代码行来制作代码时 更清楚,这绝对是一个优势。

对于其他人:理论上,编译器可以具有内置的a知识 标准函数,并应用它无法实现的优化 找到用户编写的函数或循环。在实践中,我不知道 任何编译器的。

答案 2 :(得分:0)

回答有关std::copy等潜在好处的问题。人:

据推测,好处是,库实现可能比普通循环更有效(例如,POD类型的内在函数)。例如,对于小尺寸,x86上的普通C中的memcpy可以更容易地优化为rep movsb

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

在这种情况下,为库代码对其自己的实现进行的调用发出的警告是荒谬的,并且确实需要一个错误报告。

答案 3 :(得分:0)

首先使用Copy代替for循环,对于大数据来说更快。另一方面,你得到的错误有它自己的意思,警告提醒你功能参数值可能是错误的,可能会造成损害在将来。我缓冲区溢出的风险。我建议你采用编译器自己的建议并使用-D_SCL_SECURE_NO_WARNINGS。