std::memcpy 与非平凡可复制对象的行为
对于非平凡可复制对象,std::memcpy 的行为被声明为未定义简单可复制。这是因为 memcpy 不执行任何类型检查。它只是将源对象的字节复制到目标对象中。对于非 TriviallyCopyable 类型的对象,这可能会导致意外行为。
例如,让我们考虑以下结构:
struct Entity { int health; int damage; };
int 和 Entity 都不是 TriviallyCopyable。如果我们使用 std::memcpy 来复制这种类型的对象,我们可能会得到意想不到的结果。例如,以下代码可能会导致程序崩溃:
void swapEntities(Entity* e1, Entity* e2) { memcpy(e1, e2, sizeof(Entity)); }
此代码通过将 e2 的字节复制到 e1 来交换 e1 和 e2 的值。然而,这并不能正确处理实体不可平凡复制的问题。 Entity 的构造函数和析构函数不会被调用,e1 和 e2 的值可能会处于不一致的状态。
为了避免未定义的行为,重要的是使用适当的函数来复制非 TriviallyCopyable 的对象。 std::copy 和 std::swap 是两个保证可以安全地与任何类型的对象一起使用的函数。
在 cppreference 上 memcpy 的更新描述中,注意到以下例外:“除非程序不依赖于目标对象的析构函数(不是由 memcpy 运行)的效果,并且目标对象的生命周期(由 memcpy 结束,但不是由 memcpy 启动)由其他某个对象启动意味着,例如placement-new。”
此异常允许memcpy在某些有限的情况下与非TriviallyCopyable对象一起使用。但是,请务必注意,这是一个例外,并且避免将 memcpy 与非 TriviallyCopyable 对象一起使用通常仍然更安全。
以上是什么时候对非平凡可复制对象使用'std::memcpy”是安全的?的详细内容。更多信息请关注PHP中文网其他相关文章!