Search code examples
c++fstreamifstreamunique-ptr

Creating a unique_ptr from ifstream in binary


I wish to load an object saved in a binary file using ifstream. Currently the pointer is not initialized and the application crashes. I am not 100% sure how to do this with unique_ptr. I imagine I will have to release the old object before reading the values.

In my main constructor:

typedef unique_ptr<Character> charPTR;
myCharacter_ = charPTR(new Character());

I try to load it as so:

    ifs.read(reinterpret_cast<char*>(&myCharacter_), sizeof(myCharacter_));

Saving the object actually works:

    ofs.write(reinterpret_cast<const char*>(&myCharacter_), sizeof(myCharacter_));

Thank you for any help, I am not really used to unique_ptr but I thought it represented my storage struct perfectly.


Solution

  • Jonathan Potter has already given you a solution but I'll tell you why it works and why it didn't before.

    When you write out:

    ofs.write(reinterpret_cast<const char*>(&myCharacter_), sizeof(myCharacter_));
    

    You are taking the address of myCharacter which is a std::unique_ptr and casting that pointer to a const char * when it is in fact the object which contains that pointer. So what you have is basically equivalent to a const char ** and you are casting it to a const char *.

    By calling myCharacter.get() you are retrieving the stored raw pointer which is of Character * type (which I am assuming you have assured is identical in memory layout to a char *) and casting it to a const char *.

    Now ofstream has an overload which takes a const char * and assumes it is a null terminated string and attempts to write that out. Yours isn't a null terminated string but by passing in sizeof(Character) (which I am assuming is equivalent to sizeof(char)) you assure it only tries to access one character anyway. You could perhaps make this more explicit by doing *myCharacter.get() and serialising the value type.

    More generally, if Character really is just a char then I don't see any point in ever having a unique_ptr of it. The cost of copying a char is always going to be less than dereferencing that pointer and in fact the size of the pointer itself is always going to be far larger than the char.