Is it correct to save an object in a binary?


The following code has a class and saves an object in a binary. Traditionally, a struct is made that will store the int attribute in the binary. But the code as it is works. My question is, can a code like that be used? Is it "legal"? It can be dangerous for some reason? [Edit: the size of the resulting binary is 4 bytes.]

#include <iostream>
#include <fstream>
using namespace std;

class A{
    int a;
    A(int a_):a(a_){}

    int Ver(){return a;}

int main(int argc, char *argv[]) {
    fstream archivo("dato.dat", ios::binary | ios::in | ios::out | ios::trunc);
        cerr << "Error al abrir dato.dat";
        A objeto(4);
    return 0;
asked by NotHaveOne 31.12.2018 в 00:26

1 answer


Can a code like this be used?

It depends.


Is it "legal"?

Depends on what you understand by legal . The compiler will let you do it, but for this you will have to resort to conversions inherited from C or to reinterpret_cast , which already denotes that you are doing something weird.


Can it be dangerous for some reason?

Of course I do, keep reading.

In C ++ objects (either structures or classes), are complex elements that may contain more information than initially expected.

The only drawback when saving the binary information of an object in memory are the pointers. In C ++, it is usual for objects to store information in dynamic memory and, to access said information, the object will use a pointer. Saving the binary information as is implies that the information stored in the dynamic memory will not be stored , but the contents of the pointer will be stored, that is, an address of memory . When the state of the object is subsequently recovered, almost certainly the recovered memory address will be invalid and the program will have difficulties to function normally.

Thus, a class as usual in C ++ as class std::string , as well as any of its derivatives QString , AnsiString , ... make use of dynamic memory. It is easy to see then that nothing that a class makes use of text strings will already have problems.

But is that even if our object does not declare pointers or use classes that pull dynamic memory can continue to encounter problems ... It can happen that our class (or one of its base class, have virtual functions). At the moment in which a class declares a function as virtual, the compiler will create a table of functions, that is not more than an array of pointers to function. This table will be used by the program to know which virtual function to call at each moment (the essence of polymorphism).

Although this table of functions is not directly available to the programmer, it is easy to prove its existence:


struct A
  virtual ~A() {}

struct B
  ~B() { }

int main()
  std::cout << sizeof(A) << ' ' << sizeof(B);

In my case , the program returns the following:

8 1

The class A , having virtual functions, is forced to use a table of functions. Since the standard does not specify how this table should be implemented, there is the possibility that it is in the dynamic memory, which reproduces the problem of pointers.

So, to avoid incomprehensible problems, it is best to create routines that serialize the different objects to ensure that their status can be subsequently recovered safely. It's more work but in return you get a robust and stable solution.

answered by 31.12.2018 / 02:15