2

If I have a class that has primitives in it, a bunch of ints or chars for example, is it possible to do deserialize and serialize it with memcpy?

MyClass toSerialize;
unsigned char byteDump[sizeof(toSerialize)];
memcpy(&byteDump, &toSerialize, sizeof(toSerialize));
WriteToFile(byteDump);

Then on another program or computer, do this:

MyClass toDeserialize;
unsigned char byteDump[sizeof(toSerialize)];
LoadFile(byteDump);
memcpy(&toDeserialize, &byteDump, sizeof(byteDump));

I have cases where this does in fact work in the same program. But if I try to run it on other programs or PCs, it sometimes does not work and MyClass will have different values. Is this safe to do or not?

user99999991
  • 1,351
  • 3
  • 19
  • 43
  • At least, endianness issue. – Jarod42 Apr 23 '18 at 21:16
  • 3
    Unless `MyClass` is a [POD type](http://en.cppreference.com/w/cpp/concept/PODType) then no you can't use `memcpy` for deserialization *or* the serialization in the first place. And even if it *is* a POD type you could have problems with e.g. endianness issues and possible other incompatibilities between platforms and compilers. – Some programmer dude Apr 23 '18 at 21:16
  • 1
    Also, potentially different class layout regarding padding. – Baum mit Augen Apr 23 '18 at 21:16
  • Also note that pointers can't be serialized as-is. Not even between different processes of the same program (on a modern protected virtual memory OS). – Some programmer dude Apr 23 '18 at 21:20
  • @Someprogrammerdude wouldn't a pointer still qualify as POD? – Drew Dormann Apr 23 '18 at 21:27
  • 2
    @DrewDormann Unfortunately it does. But doing a byte-wise copy of a pointer (which is what `memcpy` does) just copies the pointer and not what it points to. – Some programmer dude Apr 23 '18 at 21:34

2 Answers2

3

Is this safe to do or not?

Between different programs or platforms, memcpy is not safe. You are not assured that the byte layout of a type will be consistent.

Within the same program on the same platform, a well-formed* type T may be serialized with memcpy only if is_trivially_copyable_v<T> is true.

std::atomic is a type that takes advantage of certain types being bytewise copyable.


*A type T is considered "well formed" if there are not bugs in the defined or defaulted constructors, assignment operators, or destructor.

Drew Dormann
  • 59,987
  • 13
  • 123
  • 180
1

In short, no. memcpy() was not designed for this. Having said that, you can get away with it if you don't care about cross-platform issues, for both data and executable.

As long as data is stored and retrieved consistently, memcpy() won't care.

donjuedo
  • 2,475
  • 18
  • 28