我正在制作一个序列化数据结构并将其发送到服务器的程序。序列化功能在使用时失效的问题或多或少是40次左右。
我正在使用 Visual Studio Community 2015 , boost 1.59 32bits 和 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);
}
在实际代码中,函数 SerializeAndSend 被称为aprox的40倍。
我可以肯定地说,90%的序列化结构被初始化并且没有任何错误的值。
我尝试清理客户端和服务器中的项目。他们使用的RAM非常低,或多或少13mb。
我不知道为什么它在使用时失败而不是第一次失败。
答案 0 :(得分: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
(和相关函数)中。
如果您在平台上发现问题,请考虑(内存)分析并启用调试堆以进行诊断。