这纯粹是假设,但我不确定以下代码是否会根据 C++ 规范导致未定义的行为。我想复制一个对象中的字节,通过用零覆盖它来爆炸对象,然后将旧字节复制回来。我可以这样做而不会导致未定义的行为吗?
示例代码:
NonPODType o;
char bytes[sizeof(o)];
memcpy(bytes, &o, sizeof(o));
memset(&o, 0, sizeof(o));
memcpy(&o, bytes, sizeof(o));
这纯粹是假设,但我不确定以下代码是否会根据 C++ 规范导致未定义的行为。我想复制一个对象中的字节,通过用零覆盖它来爆炸对象,然后将旧字节复制回来。我可以这样做而不会导致未定义的行为吗?
示例代码:
NonPODType o;
char bytes[sizeof(o)];
memcpy(bytes, &o, sizeof(o));
memset(&o, 0, sizeof(o));
memcpy(&o, bytes, sizeof(o));
一般来说,没有。明确保证这适用于第 3.9/2 节中的可简单复制的类型,但对于其他类型则没有。
对于普通可复制 type 的任何对象(基类子对象除外)
T
,无论该对象是否拥有 type 的有效值T
,构成该对象的底层字节(1.7)都可以复制到char
or的数组中unsigned char
。char
如果or的数组的内容unsigned char
被复制回对象,则该对象随后应保持其原始值。[示例:#define N sizeof(T) char buf[N]; T obj; // obj initialized to its original value std::memcpy(buf, &obj, N); // between these two calls to std::memcpy, // obj might be modified std::memcpy(&obj, buf, N); // at this point, each subobject of obj of scalar type // holds its original value
—结束示例]
一般来说,是的。破坏的唯一方法是,如果您在销毁对象之后和恢复其数据之前访问该对象:
memset(&o, 0, sizeof(o));
obj.doSomething(); <--- 休息
memcpy(&o, 字节, sizeof(o));