2012-03-13 2 views
3

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

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

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) 
{ 
    .... 
} 

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

terminate called after throwing an instance of 'std::length_error'
what(): basic_string::resize

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

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

+0

'string :: resize' будет вызывать' length_error' только тогда, когда кто-то пытается сделать 'size()' больше, чем 'max_size()'. Это практически невозможно, если платформа не ограничивает размер распределения. –

+0

Я думаю, потому что text_archive почти не имеет структуры, большинство ошибок будут такого типа, а не archive_exception, может быть, если вы используете другой тип архива, например xml, будет возникать проблема archive_exception. Решение состоит в том, чтобы поймать родительское стандартное исключение и в зависимости от приложения, чтобы восстановить любое исключение, более информативное для вашей программы. – alfC

+0

@alfC: Я надеялся (и действительно ожидал), что эти исключения будут пойманы архиватором. Я ловил archive_exception, но не исключения std. Теперь я добавил std :: excpetion в catch, и теперь он работает. – Borkhuis

ответ

0

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

Ваша линия

archive & this->string2; 

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

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