使用boost序列化时会崩溃很多次

问题描述 投票:2回答:1

我正在制作一个序列化数据结构并将其发送到服务器的程序。当序列化功能在使用时失败,或多或少40次左右时出现问题。

我正在使用Visual Studio Community 2015,提升1.59 32位和winsock2,该程序使用32位架构进行编译。

错误是:

Test.exe中的0x772BE3C6(ntdll.dll)中产生异常:0xC0000005:读取位置0x3838E1A9的访问冲突。

这是一个使用崩溃函数的简单示例:

#define WIN32_LEAN_AND_MEAN

#include <WinSock2.h>
#include <WS2tcpip.h>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/iostreams/device/back_inserter.hpp>
#include <boost/iostreams/device/array.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/iostreams/stream.hpp>

struct StructFunction 
{
    char function;
    int arguments;

    template<class Archive>
    void serialize(Archive &ar, const unsigned int version)
    {
        ar & function;
        ar & arguments;
    }
};
BOOST_CLASS_IMPLEMENTATION(StructFunction, boost::serialization::object_serializable)

bool Send(std::string buffer)
{
    int iResult = send(ConnectSocket, buffer.data(), buffer.size(), 0);

    if(iResult == SOCKET_ERROR)
    {
        printf("send failed: %d\n", WSAGetLastError());
        Stop();
        return false;
    }

    return true;
}

int SerializeAndSend(StructFunction structFunction)
{
    // serialize obj into an std::string
    std::string serial_str;
    serial_str.clear();

    boost::iostreams::back_insert_device<std::string> inserter(serial_str);
    boost::iostreams::stream<boost::iostreams::back_insert_device<std::string> > 
        s(inserter);
    boost::archive::binary_oarchive oa(s); // This throws the error

    oa << structFunction;

    // flush the stream to finish writing into the buffer
    s.flush();

    Send(serial_str);

    return 1;
}

int main(int argc, char* argv[])
{
    ConnectSocket = /* We create a socket that is connected to the server using winsock2 */

    StructFunction structFunction;
    structFunction.function = "A";
    structFunction.parameter = 1;

    SerializeAndSend(structFunction);
}

在实际代码中,函数Serialize And Send被称为40次约。

我可以肯定地说,90%的序列化结构被初始化并且没有任何错误的值。

我试图清理客户端和服务器中的项目。他们使用的RAM非常低,或多或少13mb。

我不知道为什么它在使用时失败而不是第一次失败。

c++ boost boost-asio
1个回答
2
投票

消除原因的想法是使事物非常独立,只是观察它是否仍然重现/一个问题:

Live On Coliru

#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/iostreams/device/back_inserter.hpp>
#include <boost/iostreams/device/array.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/iostreams/stream.hpp>

struct StructFunction 
{
    char function;
    int arguments;

    template<class Archive>
    void serialize(Archive &ar, const unsigned int version)
    {
        ar & function;
        ar & arguments;
    }
};

BOOST_CLASS_IMPLEMENTATION(StructFunction, boost::serialization::object_serializable)

bool Send(std::string buffer)
{
/*
 *    int iResult = send(ConnectSocket, buffer.data(), buffer.size(), 0);
 *
 *    if(iResult == SOCKET_ERROR)
 *    {
 *        printf("send failed: %d\n", WSAGetLastError());
 *        Stop();
 *        return false;
 *    }
 */

    return true;
}

int SerializeAndSend(StructFunction structFunction)
{
    // serialize obj into an std::string
    std::string serial_str;

    namespace bio = boost::iostreams;

    {
        bio::stream<bio::back_insert_device<std::string> > s(serial_str);
        boost::archive::binary_oarchive oa(s);
        oa << structFunction;
    }

    static bool do_init = true;
    if (do_init) {
        std::cout << "DEBUG: \n";
        for (uint8_t ch : serial_str)
            std::cout << std::setw(2) << std::setfill('0') << std::showbase << std::hex << static_cast<int>(ch) << " ";
        do_init = false;
    }

    Send(serial_str);

    return 1;
}

int main()
{
    //ConnectSocket = [> We create a socket that is connected to the server using winsock2 <]

    for (auto i = 0ull; i< 1ull << 22; ++i) {
        StructFunction structFunction;
        structFunction.function = 'A';
        structFunction.arguments = 1;

        SerializeAndSend(structFunction);
    }
}

正如你所看到的,输出不是很多麻烦

DEBUG: 
0x16 00 00 00 00 00 00 00 0x73 0x65 0x72 0x69 0x61 0x6c 0x69 0x7a 0x61 0x74 0x69 0x6f 0x6e 0x3a 0x3a 0x61 0x72 0x63 0x68 0x69 0x76 0x65 0xd 00 0x4 0x8 0x4 0x8 0x1 00 00 00 0x41 0x1 00 00 00 
real    0m24.026s
user    0m24.010s
sys 0m0.000s

接下来是什么?

在您的系统上试一试。如果没关系,则问题出在Send(和相关函数)中。

如果您在平台上发现问题,请考虑(内存)分析并启用调试堆以进行诊断。

© www.soinside.com 2019 - 2024. All rights reserved.