首页 > 解决方案 > 使用 std::memcpy 复制包含 boost::any 数据成员的对象

问题描述

我正在尝试boost::any通过网络 API 传递一个包含数据成员的对象,以在两个应用程序之间交换数据。我知道 API 在memcpy内部使用来复制数据,但我不确定我想要做的是否是调用未定义的行为。

我写了一个简单的例子来演示memcpy以这种方式使用:

#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);
}

此代码似乎可以工作,并打印以下输出:

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

但是根据Data对象中存储的类型,大小不会改变吗?无论我使用什么类型,它总是打印出尺寸为8.

这段代码是否调用了未定义的行为?如果是,我该如何修复它,以便我可以正确地memcpy创建一个包含boost::any数据成员的对象?

标签: c++undefined-behaviormemcpyboost-any

解决方案


any包含一个指针,并具有一个析构函数,并且总体上是您不想要的memcpy。它在这里工作是因为两者srcdst都在相同的内存空间中,并且因为您在free不运行析构函数的情况下调用对象。

对于由(返回的对象)memcpy持有的指向对象可能没问题。它本身或包含它的对象绝对不行anyany_castmemcpyany


推荐阅读