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?
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 free
ing 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.