Search code examples
c++arraysvisual-studioc++11deep-copy

What is the benefit of using std::copy instead of manual for loop to copy dynamic array?


Suppose I have the following code:

int* intPtr = new int[5];

// ...do stuff...


And now I want to copy intPtr to a new, identical, array:

int* newIntPtr = new int[5];


This can be done using either a simple for-loop or std::copy():

  1. Using a for loop

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

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


Using std::copy(), I get a warning in Visual Studio:

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


I could use stdext::checked_array_iterator<int*> to make the warning go away:

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

but that means the code won't compile on anything else than Visual Studio.

So, how should I solve this? Should I use the simple for loop and effectively avoid the warning, or should I use std::copy() and do something to avoid the warning? Obviously, I could disable the warning, but that doesn't seem like a proper solution... or is it?


Solution

  • There are a few benefits for using std::copy over a loop:

    1. The call is self-documenting. A reader of your call instantly knows what was the intent of the statement without having to read comments or figuring out what the loop is doing
    2. It may be optimized for simple types as in you case :

    In practice, implementations of std::copy avoid multiple assignments and use bulk copy functions such as std::memmove if the value type is TriviallyCopyable source

    1. More maintainable. Your container is more easily replaceable in the future. You only need to change the parameters to copy and not implementation

    As other comments have mentioned, both, the loop and copy calls are equally unsafe so the warning is misleading. However, I would avoid disabling security warnings for the whole application. Instead, disable locally with #pragma warning (suppress: nnnn), see here.