Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Boost c++ serializing a char *

I have a class and I am trying to serialize a shared_ptr but the normal method of serializing an object is not working:

class Object {
public:
    Object();
    ~Object();

    shared_ptr<char>objectone;

    friend class boost::serialization::access;
    template <typename Archive>
    void serialize(Archive &ar, const unsigned int version)
    {
        ar & objectone;
    }
};

I've even attempted it in this way but it still doesn't work:

    void serialize(Archive &ar, const unsigned int version)
    {
        for (int i = 0; i < (strlen(objectone.get())); i++)
             ar & objectone.get()[i];
    }

Any ideas how to approach this? Thanks.

Some extra information:

I've already included both shared_ptr header files:

#include <boost/serialization/shared_ptr.hpp>
#include <boost/serialization/shared_ptr_132.hpp>

I've attempted to convert to a string and serialize it in that way but it produces the following error: boost::archive::archive_exception' what(): stream error

friend class boost::serialization::access;
template <typename Archive>
void serialize(Archive &ar, const unsigned int version)
{
    if (objectone.get()) {
        string temp(objectone.get());
        ar & temp;
    }
    ar & objectone;
}
like image 877
user459811 Avatar asked Feb 23 '11 17:02

user459811


2 Answers

There's more than just one problem with your code.

First, shared_ptr is not meant to hold arrays. Stop doing that.

Second, the serialization library doesn't save C-style strings that I know of. It would be pretty hard to implement and basically pointless since you can save vector or string, which is what you should be using anyway.

If you really insist on keeping a char* string then you need to convert it into a vector/string, and save it. Then upon reading you need to read that vector/string back, get the size, allocate the memory, stick it in...etc... Pointer tracking is not going to work so if you're relying on that you'll have to implement it yourself. Have fun.

New code edit:

You're doing the save bit in a function that covers both save and load. It of course doesn't work very well wrt loading. You need to split your serialization. if (Archive::is_saving) won't work either. The boost documentation explains how to correctly split the serialization routine.

like image 90
Edward Strange Avatar answered Sep 19 '22 16:09

Edward Strange


Keep in mind what Crazy Eddie said about shared_ptr not being the right tool for the job. Since you don't have the flexibility to change the class definition here is a work around.

boost::serialization provides a wrapper make_array that takes a pointer and wraps it up as an array for the serialization. This requires the array size to be known prior to serialization.

You could then do something like:

void serialize(Archive &ar, const unsigned int version)
{
    ar & array_size; // Figure out how to determine this (perhaps strlen(objectone.get())

    if (ar::is_loading)
    {
        objectone.reset(new char[array_size]); // allocate the array before we load it
    }

    if (objectone.get() != NULL)
    {
        ar & make_array(objectone.get(), array_size);
    }
}

That code sample is pretty rudimentary but conveys the concept.

like image 39
tallganglyguy Avatar answered Sep 21 '22 16:09

tallganglyguy