Click here to Skip to main content
15,881,248 members
Articles / Programming Languages / C++
Tip/Trick

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

Rate me:
Please Sign up or sign in to vote.
4.90/5 (5 votes)
27 Jan 2018CPOL 31.6K   84   8   1
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)


Written By
Software Developer (Senior)
Singapore Singapore
Shao Voon is from Singapore. His interest lies primarily in computer graphics, software optimization, concurrency, security, and Agile methodologies.

In recent years, he shifted focus to software safety research. His hobby is writing a free C++ DirectX photo slideshow application which can be viewed here.

Comments and Discussions

 
Suggestioncode sample doesn't actually offer memcpy alternative Pin
Stefan_Lang31-Jan-18 22:09
Stefan_Lang31-Jan-18 22:09 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.