Boost序列化抛出了std异常。

4

在测试使用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序列化器已知的(已记录的)行为吗?我可以对输入流进行检查以查看它是否有效,还是反序列化程序缺少try/catch处理?

问候,
约翰


除非平台限制了分配大小,否则string::resize仅在有人试图使size()大于max_size()时才会抛出length_error。这几乎是不可能的。 - Bo Persson
我认为由于text_archive几乎没有结构,大多数错误都会是这种类型而不是archive_exception,也许如果您使用其他存档类型,比如xml,archive_exception将被引发。解决方案是捕获父标准异常,并根据应用程序重新抛出更有信息的异常。 - alfC
@alfC:我本来希望(实际上也期望)这些异常会被归档程序捕获。我已经捕获了archive_exception,但没有捕获std异常。现在我将std::exception添加到catch中,现在它可以工作了。 - Borkhuis
1个回答

0

你正在编写一个字符串并阅读你的TestClass。

你的代码行

archive & this->string2;

代码尝试从未初始化的内存中读取数据。这意味着,您可能会尝试分配一个过大的std::string(有50%的概率,在两个字符串非常相似的情况下每次都会尝试)。

因此,异常是由您的代码引起的,所以不奇怪它没有被 archiver 捕获。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接