Memcpy non-POD object

For objects of type POD, it is guaranteed by the standard that when you memcpy the contents of your object into an array of char or unsigned char, and then memcpy the contents back into your object, the object will store its original value.

Now note that there is no such guarantee for non-POD objects. So my question is: why is this so?

Source text above

+2
c ++
07 Oct '14 at 3:05
source share
3 answers

The reason why the trivially copied class (C ++ 11 mainly uses the concepts of the trivial class and the standard layout class instead of the POD) may be memcpy'ed not related to dynamic allocation, as other answers / comments suggest. If you try to make a shallow copy of a type with dynamic allocation, you are causing problems. But you may well have a type with a pointer that performs dynamic allocation in a user-provided constructor (if it has a default constructor) and qualifies as a trivial class.

The actual reason memcpy can be guaranteed is because trivially-copied (as well as standard layouts) types are required to write adjacent storage bytes, while other objects are not.

N3690

1.8.5 If it is not a bit field (9.6), the most derived object must have a nonzero size and must occupy one or more bytes of memory. Base class subobjects can be zero size. A trivially copied or standard layout object type (3.9) should occupy adjacent storage bytes.

+3
07 Oct '14 at 3:50
source share

I'm not sure that, strictly speaking, the standard allows you to memcpy into a char array and vice versa, although you will probably leave with it using POD.

But things get duller when you start looking at all the complicated things that C ++ can do. Consider the following:

 struct ex1; struct ex2 { ex2(std::unique_ptr<ex1> ptr) : member{ptr} {} private: std::unique_ptr<ex1> member; }; 

Line ex2 is just a move, because it has an element variable just for moving. So what happens if we use memcpy to create a bit-bit identical copy of an ex2 instance? We get two objects that both think they have a pointer to a member. What happens when the second one is removed? You get the idea.

+2
07 Oct '14 at 3:22
source share

A special case when this type of serialization fails applies to types with virtual members. If the type has a virtual member, then it has a vtable. This table will contain implementation pointers for each of the virtual members.

If the serialized data in the char array crosses the boundary of the process (you send it over the network or write to disk and read it back from another process), then the vtable pointers that you wrote out cannot last longer, and calling any virtual member will cause undefined behavior .

+2
Oct 07 '14 at 3:42 on
source share



All Articles