Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I clone the bytes of a C++ object, overwrite the original bytes, then copy those bytes back?

This is purely hypothetical, but I'm not sure whether the following code will result in undefined behavior according to the C++ spec. I'd like to make a copy of the bytes in an object, blast the object by overwriting it with zeros, then copy the old bytes back. Can I do so without causing undefined behavior?

Sample code:

NonPODType o;
char bytes[sizeof(o)];

memcpy(bytes, &o, sizeof(o));
memset(&o, 0, sizeof(o));
memcpy(&o, bytes, sizeof(o));
like image 514
templatetypedef Avatar asked Jun 08 '12 17:06

templatetypedef


2 Answers

In general, no. There's an explicit guarantee that this works for trivially copyable types on §3.9/2, but there's no such thing for other types.

For any object (other than a base-class subobject) of trivially copyable type T, whether or not the object holds a valid value of type T, the underlying bytes (1.7) making up the object can be copied into an array of char or unsigned char. If the content of the array of char or unsigned char is copied back into the object, the object shall subsequently hold its original value. [Example:

#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

—end example ]

like image 81
R. Martinho Fernandes Avatar answered Oct 25 '22 05:10

R. Martinho Fernandes


In general, yes. The only way things break is if you access the object after destroying the object and before the restitution of it's data:

memset(&o, 0, sizeof(o));

obj.doSomething(); <--- breaks

memcpy(&o, bytes, sizeof(o));

like image 27
Ideafix Avatar answered Oct 25 '22 06:10

Ideafix