Use STL copy, Not memcpy 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.

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.

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.

#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

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s

%d bloggers like this:
search previous next tag category expand menu location phone mail time cart zoom edit close