【发布时间】:2021-11-28 15:23:20
【问题描述】:
我正在尝试通过网络 API 传递一个包含 boost::any 数据成员的对象,以在两个应用程序之间交换数据。我知道 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 数据成员的对象?
【问题讨论】:
-
sizeof ( boost::any)是一个常数。不管它是什么类型,它总是一样的。 -
通常你应该永远使用
std::memcpy来复制任何C++对象。它将执行逐字节的直接复制,并且不会调用复制构造函数,这意味着可能无法以有效的方式复制复杂的对象。 -
@Someprogrammerdude 在这种情况下我别无选择,因为
memcpy在网络 API 内部被调用。我只需要确保可以使用memcpy有效地复制我传递给它的类型 -
这也是相关的:en.cppreference.com/w/cpp/types/is_trivially_copyable。如果它不是
is_trivially_copyable,那么你不能只是 memcpy 它,因为复制它需要的不仅仅是复制位和字节。any当然不是。
标签: c++ undefined-behavior memcpy boost-any