【发布时间】:2014-11-19 18:31:00
【问题描述】:
标准定义我们可以通过以下方式使用 std::memcpy int:
对于任何可平凡复制的类型 T,如果指向 T 的两个指针指向 不同的 T 对象 obj1 和 obj2,其中 obj1 和 obj2 都不是 基类子对象,如果构成 obj1 的底层字节 (1.7) 是 复制到 obj2 中,obj2 将随后保持与 obj1 相同的值。
如果我们将该函数应用于非平凡可复制类型的对象,我们可能会遇到什么潜在问题?下面的代码就像它适用于普通可复制类型一样工作:
#include <iostream>
#include <cstring>
using std::cout;
using std::endl;
struct X
{
int a = 6;
X(){ }
X(const X&)
{
cout << "X()" << endl;
}
};
X a;
X b;
int main()
{
a.a = 10;
std::memcpy(&b, &a, sizeof(X));
cout << b.a << endl; //10
}
【问题讨论】:
-
明显 UB 是显而易见的。例如,考虑
memcpy'ingstd::vector。 -
嗯,是的,它可以工作,因为 struct X 可以简单地复制。例如,如果结构的成员包括任何类型的堆分配内存,那么您就会遇到问题。好吧,在一个真正的程序中。不在您的测试中。
-
@Wlerin X 不可轻易复制。
-
@T.C.嗯。它有一个什么也不做的复制构造函数。这可能足以在技术上 使其不易复制,但类的实际内容可以逐个成员地复制而不会出现问题。在 C++11 之前,b = a 的结果也将与 memcpy 的结果相同。无论哪种方式,这个示例程序都不是一个很好的例子。
-
您的实际问题是什么?你想让我们向你解释什么是未定义的行为吗?还是您只是想确认这实际上是未定义的行为?