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?
anycontains a pointer, and has a destructor, and is overall something you don't want tomemcpy. It's working here because bothsrcanddstare in the same memory space and because you’refreeing the object without running the destructor.It's potentially okay to
memcpythe pointed-to object held by theany(the object returned byany_cast). It is definitely not okay tomemcpytheanyitself, or an object containing it.