Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C++

C++ Tip: Use STL copy, Not memcpy to Copy Array

4.90/5 (5 votes)
27 Jan 2018CPOL 33K   86  
Do not use memcpy directly to copy array

Many C++ developers like to use memcpy() to copy POD arrays to extract the maximum performance during the copy. See the POD structure below.

C++
struct MyStruct
{
    int n;
    double d;
};

What if a new unsuspecting developer adds a string member and is not aware that the code uses memcpy() to do copying? memcpy() only makes shallow copies. The code no longer works correctly. This is where STL copy() comes to the rescue. If the array contains type which is TriviallyCopyable, it calls memmove(), else it calls the assignment operator. The calls are determined at compile time. memmove() is similar to memcpy() that they both do copying, except memmove() allows the destination and source to overlap.

C++
struct MyStruct
{
    int n;
    double d;
    std::string s; // Unsuspecting developer add this member!
};

Use the debugger to step into the first copy() you find it uses memmove() while the second copy() does not.

C++
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>

// TriviallyCopyable structure
struct MyStruct
{
    int n;
    double d;
};

struct MyStruct2
{
    int n;
    double d;
    std::string s;
};

int main()
{
    std::vector<MyStruct> v1{ {1, 1.0}, {2, 2.0} };
    std::vector<MyStruct> v2{ 2 };
    std::copy(v1.begin(), v1.end(), v2.begin()); // calls memmove()

    for (const auto& o : v2)
    {
        std::cout << "After v2 copy, n:" << o.n << ", d:" << o.d << std::endl;
    }
    std::vector<MyStruct2> v3{ { 1, 1.0, "Hello" },{ 2, 2.0, "World" } };
    std::vector<MyStruct2> v4{ 2 };
    std::copy(v3.begin(), v3.end(), v4.begin()); // Does not call memmove()

    for (const auto& o : v4)
    {
        std::cout << "After v4 copy, n:" << o.n << ", d:" << o.d << ", s:" << o.s << std::endl;
    }

    return 0;
}

The tip is to use STL copy() wherever possible to copy array. copy() delegates the calls to memmove() when the type is TriviallyCopyable.

References

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)