Сериализация Boost выдает исключение std

При тестировании некоторого кода, использующего сериализатор Boost, я увидел, что при десериализации выдается ошибка std::length_error. Я запускаю приведенный ниже код в Linux (в Windows я не видел этой проблемы). Я использую Boost 1.47.0.

Мой класс сериализации:

class TestClass
{
public:
    TestClass() {};

    TestClass(const char* string1, const char* string2, const char* string3):
        string1(string1),
        string2(string2),
        string3(string3)
    {};

    template<class Archive>
    void serialize(Archive & archive, const unsigned int version)
    {
        // When the class Archive corresponds to an output archive, the
        // & operator is defined similar to <<.  Likewise, when the class Archive
        // is a type of input archive the & operator is defined similar to >>.
        archive & this->string1;
        archive & this->string2;
        archive & this->string3;
    }

    std::string string1;
    std::string string2;
    std::string string3;
};

Мой тестовый код:

TestClass testClass;
std::string value("nonsense");
try
{
    std::stringstream stringStream;
    stringStream << value;
    boost::archive::text_iarchive serializer(stringStream);
    serializer >> testClass;
}
catch (const boost::archive::archive_exception& e)
{
    ....
}

При выполнении этого кода я получаю std::length_error:

завершение вызывается после создания экземпляра 'std::length_error'
what(): basic_string::resize

Является ли это известным (задокументированным) поведением сериализатора Boost, могу ли я проверить входной поток, чтобы убедиться, что он действителен, или в десериализаторе отсутствует попытка/поймать?

С уважением,
Йохан


person Borkhuis    schedule 13.03.2012    source источник
comment
string::resize выдаст length_error только тогда, когда кто-то попытается сделать size() больше, чем max_size(). Это почти невозможно, если только платформа не ограничила размер распределения.   -  person Bo Persson    schedule 13.03.2012
comment
Я думаю, что из-за того, что text_archive почти не имеет структуры, большинство ошибок будут такого рода, а не archive_exception, возможно, если вы используете другой тип архива, например xml, будет поднято archive_exception. Решение состоит в том, чтобы поймать родительское стандартное исключение и, в зависимости от приложения, повторно выдать любое исключение, более информативное для вашей программы.   -  person alfC    schedule 14.03.2012
comment
@alfC: я надеялся (и на самом деле ожидал), что эти исключения будут обнаружены архиватором. Я ловил archive_exception, но не стандартные исключения. Теперь я добавил std::excpetion в улов, и теперь он работает.   -  person Borkhuis    schedule 20.03.2012


Ответы (1)


Вы пишете строку и читаете свой TestClass.

Ваша линия

archive & this->string2;

уже пытается читать из неинициализированной памяти. Это означает, что вы, вероятно, пытаетесь выделить std::string слишком большого размера (в 50% случаев, когда две строки очень похожи каждый раз).

Таким образом, исключение исходит из вашего кода и неудивительно, что оно не отлавливается архиватором.

person Uli Klank    schedule 21.08.2013