c++undefined-behaviormemcpyboost-any

Using std::memcpy to copy an object that contains a boost::any data member


I am trying to pass an object that contains a boost::any data member through a networking API to exchange data between two applications. I know that the API uses memcpy internally to copy the data, but I'm not sure if what I am trying to do is invoking undefined behavior.

I wrote up a simple example to demonstrate using memcpy in this way:

#include <boost/any.hpp>
#include <cstring>
#include <string>
#include <iostream>

class Data
{
public:
    template <typename T>
    Data(T value)
        : m_value(value)
    {}

    template <typename T>
    T Read() const
    {
        return boost::any_cast<T>(m_value);
    }

private:
    boost::any m_value;
};

int main()
{
    Data src(std::string("This is some data."));
    std::cout << "Size: " << sizeof(src) << std::endl;
    std::cout << "SRC: " << src.Read<std::string>() << std::endl;

    void* dst = malloc(sizeof(src));
    std::memcpy(dst, &src, sizeof(src));

    const auto data = static_cast<Data*>(dst);
    std::cout << "DST: " << data->Read<std::string>() << std::endl;

    std::free(dst);
}

This code appears to work, and prints the following output:

Size: 8
SRC: This is some data.
DST: This is some data.

But depending on the type stored in the Data object wouldn't the size change? No matter what type I use it always prints that the size is 8.

Is this code invoking undefined behavior? If it is, how can I fix it so I can properly memcpy an object that contains a boost::any data member?


Solution

  • any contains a pointer, and has a destructor, and is overall something you don't want to memcpy. It's working here because both src and dst are in the same memory space and because you’re freeing the object without running the destructor.

    It's potentially okay to memcpy the pointed-to object held by the any (the object returned by any_cast). It is definitely not okay to memcpy the any itself, or an object containing it.